コード例 #1
0
ファイル: _posemath.c プロジェクト: 13788593535/machinekit
int pmRotNorm(PmRotationVector const * const r, PmRotationVector * const rout)
{
    double size;

    size = pmSqrt(pmSq(r->x) + pmSq(r->y) + pmSq(r->z));

    if (rtapi_fabs(r->s) < RS_FUZZ) {
	rout->s = 0.0;
	rout->x = 0.0;
	rout->y = 0.0;
	rout->z = 0.0;

	return pmErrno = 0;
    }

    if (size == 0.0) {
#ifdef PM_PRINT_ERROR
	pmPrintError("error: pmRotNorm size is zero\n");
#endif

	rout->s = 0.0;
	rout->x = 0.0;
	rout->y = 0.0;
	rout->z = 0.0;

	return pmErrno = PM_NORM_ERR;
    }

    rout->s = r->s;
    rout->x = r->x / size;
    rout->y = r->y / size;
    rout->z = r->z / size;

    return pmErrno = 0;
}
コード例 #2
0
ファイル: _posemath.c プロジェクト: 13788593535/machinekit
int pmQuatNorm(PmQuaternion const * const q1, PmQuaternion * const qout)
{
    double size = pmSqrt(pmSq(q1->s) + pmSq(q1->x) + pmSq(q1->y) + pmSq(q1->z));

    if (size == 0.0) {
#ifdef PM_PRINT_ERROR
	pmPrintError("Bad quaternion in pmQuatNorm\n");
#endif
	qout->s = 1;
	qout->x = 0;
	qout->y = 0;
	qout->z = 0;

	return pmErrno = PM_NORM_ERR;
    }

    if (q1->s >= 0.0) {
	qout->s = q1->s / size;
	qout->x = q1->x / size;
	qout->y = q1->y / size;
	qout->z = q1->z / size;

	return pmErrno = 0;
    } else {
	qout->s = -q1->s / size;
	qout->x = -q1->x / size;
	qout->y = -q1->y / size;
	qout->z = -q1->z / size;

	return pmErrno = 0;
    }
}
コード例 #3
0
ファイル: _posemath.c プロジェクト: 13788593535/machinekit
int pmCartCartDisp(PmCartesian const * const v1, PmCartesian const * const v2,
        double *d)
{
    *d = pmSqrt(pmSq(v2->x - v1->x) + pmSq(v2->y - v1->y) + pmSq(v2->z - v1->z));

    return pmErrno = 0;
}
コード例 #4
0
ファイル: _posemath.c プロジェクト: 13788593535/machinekit
int pmCylSphConvert(PmCylindrical const * const c, PmSpherical * const s)
{
    s->theta = c->theta;
    s->r = pmSqrt(pmSq(c->r) + pmSq(c->z));
    s->phi = rtapi_atan2(c->z, c->r);
    return pmErrno = 0;
}
コード例 #5
0
ファイル: _posemath.c プロジェクト: 13788593535/machinekit
int pmQuatRotConvert(PmQuaternion const * const q, PmRotationVector * const 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 * rtapi_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;
}
コード例 #6
0
ファイル: _posemath.c プロジェクト: 13788593535/machinekit
int pmRotMatConvert(PmRotationVector const * const r, PmRotationMatrix * const 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;
}
コード例 #7
0
ファイル: _posemath.c プロジェクト: 13788593535/machinekit
int pmCartCylConvert(PmCartesian const * const v, PmCylindrical * const c)
{
    c->theta = rtapi_atan2(v->y, v->x);
    c->r = pmSqrt(pmSq(v->x) + pmSq(v->y));
    c->z = v->z;

    return pmErrno = 0;
}
コード例 #8
0
ファイル: _posemath.c プロジェクト: 13788593535/machinekit
int pmRotIsNorm(PmRotationVector const * const r)
{
    if (rtapi_fabs(r->s) < RS_FUZZ ||
	rtapi_fabs(pmSqrt(pmSq(r->x) + pmSq(r->y) + pmSq(r->z))) - 1.0 < UNIT_VEC_FUZZ)
    {
	return 1;
    }

    return 0;
}
コード例 #9
0
ファイル: _posemath.c プロジェクト: 13788593535/machinekit
int pmCartSphConvert(PmCartesian const * const v, PmSpherical * const s)
{
    double _r;

    s->theta = rtapi_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 = rtapi_atan2(_r, v->z);

    return pmErrno = 0;
}
コード例 #10
0
ファイル: tc.c プロジェクト: AndreasHFA/machinekit
double pmCircle9Target(PmCircle9 const * const circ9)
{

    double helix_z_component;   // z of the helix's cylindrical coord system
    double helix_length;

    pmCartMag(&circ9->xyz.rHelix, &helix_z_component);
    double planar_arc_length = circ9->xyz.angle * circ9->xyz.radius;
    helix_length = pmSqrt(pmSq(planar_arc_length) +
            pmSq(helix_z_component));
    return helix_length;
}
コード例 #11
0
PmCartesian tcGetStartingUnitVector(TC_STRUCT *tc) {
    PmCartesian v;

    if(tc->motion_type == TC_LINEAR || tc->motion_type == TC_RIGIDTAP) {
        pmCartCartSub(tc->coords.line.xyz.end.tran, tc->coords.line.xyz.start.tran, &v);
    } else {
        PmPose startpoint;
        PmCartesian radius;
        PmCartesian tan, perp;

        pmCirclePoint(&tc->coords.circle.xyz, 0.0, &startpoint);
        pmCartCartSub(startpoint.tran, tc->coords.circle.xyz.center, &radius);
        pmCartCartCross(tc->coords.circle.xyz.normal, radius, &tan);
        pmCartUnit(tan, &tan);

        pmCartCartSub(tc->coords.circle.xyz.center, startpoint.tran, &perp);
        pmCartUnit(perp, &perp);

        pmCartScalMult(tan, tc->maxaccel, &tan);
        pmCartScalMult(perp, pmSq(0.5 * tc->reqvel)/tc->coords.circle.xyz.radius, &perp);
        pmCartCartAdd(tan, perp, &v);
    }
    pmCartUnit(v, &v);
    return v;
}
コード例 #12
0
ファイル: _posemath.c プロジェクト: 13788593535/machinekit
int pmCartUnitEq(PmCartesian * const v)
{
    double size = pmSqrt(pmSq(v->x) + pmSq(v->y) + pmSq(v->z));

    if (size == 0.0) {
#ifdef PM_PRINT_ERROR
        pmPrintError("Zero vector in pmCartUnit\n");
#endif
        return pmErrno = PM_NORM_ERR;
    }

    v->x /= size;
    v->y /= size;
    v->z /= size;

    return pmErrno = 0;
}
コード例 #13
0
ファイル: tc.c プロジェクト: BrendonYim/machinekit
double pmCircle9Target(PmCircle9 const * const circ9)
{

    double h2;
    pmCartMagSq(&circ9->xyz.rHelix, &h2);
    double helical_length = pmSqrt(pmSq(circ9->fit.total_planar_length) + h2);

    return helical_length;
}
コード例 #14
0
ファイル: _posemath.c プロジェクト: 13788593535/machinekit
int pmMatZyxConvert(PmRotationMatrix const * const m, PmEulerZyx * const zyx)
{
    zyx->y = rtapi_atan2(-m->x.z, pmSqrt(pmSq(m->x.x) + pmSq(m->x.y)));

    if (rtapi_fabs(zyx->y - (2 * PM_PI)) < ZYX_Y_FUZZ) {
	zyx->z = 0.0;
	zyx->y = (2 * PM_PI);	/* force it */
	zyx->x = rtapi_atan2(m->y.x, m->y.y);
    } else if (rtapi_fabs(zyx->y + (2 * PM_PI)) < ZYX_Y_FUZZ) {
	zyx->z = 0.0;
	zyx->y = -(2 * PM_PI);	/* force it */
	zyx->x = -rtapi_atan2(m->y.z, m->y.y);
    } else {
	zyx->z = rtapi_atan2(m->x.y, m->x.x);
	zyx->x = rtapi_atan2(m->y.z, m->z.z);
    }

    return pmErrno = 0;
}
コード例 #15
0
ファイル: _posemath.c プロジェクト: 13788593535/machinekit
int pmMatRpyConvert(PmRotationMatrix const * const m, PmRpy * const rpy)
{
    rpy->p = rtapi_atan2(-m->x.z, pmSqrt(pmSq(m->x.x) + pmSq(m->x.y)));

    if (rtapi_fabs(rpy->p - (2 * PM_PI)) < RPY_P_FUZZ) {
	rpy->r = rtapi_atan2(m->y.x, m->y.y);
	rpy->p = (2 * PM_PI);	/* force it */
	rpy->y = 0.0;
    } else if (rtapi_fabs(rpy->p + (2 * PM_PI)) < RPY_P_FUZZ) {
	rpy->r = -rtapi_atan2(m->y.z, m->y.y);
	rpy->p = -(2 * PM_PI);	/* force it */
	rpy->y = 0.0;
    } else {
	rpy->r = rtapi_atan2(m->y.z, m->z.z);
	rpy->y = rtapi_atan2(m->x.y, m->x.x);
    }

    return pmErrno = 0;
}
コード例 #16
0
ファイル: _posemath.c プロジェクト: 13788593535/machinekit
int pmMatZyzConvert(PmRotationMatrix const * const m, PmEulerZyz * const zyz)
{
    zyz->y = rtapi_atan2(pmSqrt(pmSq(m->x.z) + pmSq(m->y.z)), m->z.z);

    if (rtapi_fabs(zyz->y) < ZYZ_Y_FUZZ) {
	zyz->z = 0.0;
	zyz->y = 0.0;		/* force Y to 0 */
	zyz->zp = rtapi_atan2(-m->y.x, m->x.x);
    } else if (rtapi_fabs(zyz->y - PM_PI) < ZYZ_Y_FUZZ) {
	zyz->z = 0.0;
	zyz->y = PM_PI;		/* force Y to 180 */
	zyz->zp = rtapi_atan2(m->y.x, -m->x.x);
    } else {
	zyz->z = rtapi_atan2(m->z.y, m->z.x);
	zyz->zp = rtapi_atan2(m->y.z, -m->x.z);
    }

    return pmErrno = 0;
}
コード例 #17
0
ファイル: _posemath.c プロジェクト: 13788593535/machinekit
int pmQuatMatConvert(PmQuaternion const * const q, PmRotationMatrix * const 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.0 - 2.0 * (pmSq(q->y) + pmSq(q->z));
    m->y.x = 2.0 * (q->x * q->y - q->z * q->s);
    m->z.x = 2.0 * (q->z * q->x + q->y * q->s);

    m->x.y = 2.0 * (q->x * q->y + q->z * q->s);
    m->y.y = 1.0 - 2.0 * (pmSq(q->z) + pmSq(q->x));
    m->z.y = 2.0 * (q->y * q->z - q->x * q->s);

    m->x.z = 2.0 * (q->z * q->x - q->y * q->s);
    m->y.z = 2.0 * (q->y * q->z + q->x * q->s);
    m->z.z = 1.0 - 2.0 * (pmSq(q->x) + pmSq(q->y));

    return pmErrno = 0;
}
コード例 #18
0
void tcRunCycle(TP_STRUCT *tp, TC_STRUCT *tc, double *v, int *on_final_decel) {
    double discr, maxnewvel, newvel, newaccel=0;
    if(!tc->blending) tc->vel_at_blend_start = tc->currentvel;

    discr = 0.5 * tc->cycle_time * tc->currentvel - (tc->target - tc->progress);
    if(discr > 0.0) {
        // should never happen: means we've overshot the target
        newvel = maxnewvel = 0.0;
    } else {
        discr = 0.25 * pmSq(tc->cycle_time) - 2.0 / tc->maxaccel * discr;
        newvel = maxnewvel = -0.5 * tc->maxaccel * tc->cycle_time + 
            tc->maxaccel * pmSqrt(discr);
    }
    if(newvel <= 0.0) {
        // also should never happen - if we already finished this tc, it was
        // caught above
        newvel = newaccel = 0.0;
        tc->progress = tc->target;
    } else {
        // constrain velocity
        if(newvel > tc->reqvel * tc->feed_override) 
            newvel = tc->reqvel * tc->feed_override;
        if(newvel > tc->maxvel) newvel = tc->maxvel;

        // if the motion is not purely rotary axes (and therefore in angular units) ...
        if(!(tc->motion_type == TC_LINEAR && tc->coords.line.xyz.tmag_zero && tc->coords.line.uvw.tmag_zero)) {
            // ... clamp motion's velocity at TRAJ MAX_VELOCITY (tooltip maxvel)
            // except when it's synced to spindle position.
            if((!tc->synchronized || tc->velocity_mode) && newvel > tp->vLimit) {
                newvel = tp->vLimit;
            }
        }

        // get resulting acceleration
        newaccel = (newvel - tc->currentvel) / tc->cycle_time;
        
        // constrain acceleration and get resulting velocity
        if(newaccel > 0.0 && newaccel > tc->maxaccel) {
            newaccel = tc->maxaccel;
            newvel = tc->currentvel + newaccel * tc->cycle_time;
        }
        if(newaccel < 0.0 && newaccel < -tc->maxaccel) {
            newaccel = -tc->maxaccel;
            newvel = tc->currentvel + newaccel * tc->cycle_time;
        }
        // update position in this tc
        tc->progress += (newvel + tc->currentvel) * 0.5 * tc->cycle_time;
    }
    tc->currentvel = newvel;
    if(v) *v = newvel;
    if(on_final_decel) *on_final_decel = fabs(maxnewvel - newvel) < 0.001;
}
コード例 #19
0
ファイル: tc.c プロジェクト: BrendonYim/machinekit
/**
 * compute the total arc length of a circle segment
 */
int tcUpdateTargetFromCircle(TC_STRUCT * const tc)
{
    if (!tc || tc->motion_type !=TC_CIRCULAR) {
        return TP_ERR_FAIL;
    }

    double h2;
    pmCartMagSq(&tc->coords.circle.xyz.rHelix, &h2);
    double helical_length = pmSqrt(pmSq(tc->coords.circle.fit.total_planar_length) + h2);

    tc->target = helical_length;
    return TP_ERR_OK;
}
コード例 #20
0
ファイル: tc.c プロジェクト: AndreasHFA/machinekit
int tcCircleStartAccelUnitVector(TC_STRUCT const * const tc, PmCartesian * const out)
{
    PmCartesian startpoint;
    PmCartesian radius;
    PmCartesian tan, perp;

    pmCirclePoint(&tc->coords.circle.xyz, 0.0, &startpoint);
    pmCartCartSub(&startpoint, &tc->coords.circle.xyz.center, &radius);
    pmCartCartCross(&tc->coords.circle.xyz.normal, &radius, &tan);
    pmCartUnitEq(&tan);
    //The unit vector's actual direction is adjusted by the normal
    //acceleration here. This unit vector is NOT simply the tangent
    //direction.
    pmCartCartSub(&tc->coords.circle.xyz.center, &startpoint, &perp);
    pmCartUnitEq(&perp);

    pmCartScalMult(&tan, tc->maxaccel, &tan);
    pmCartScalMultEq(&perp, pmSq(0.5 * tc->reqvel)/tc->coords.circle.xyz.radius);
    pmCartCartAdd(&tan, &perp, out);
    pmCartUnitEq(out);
    return 0;
}
コード例 #21
0
ファイル: tp.c プロジェクト: cnc-club/linuxcnc
int tpAddCircle(TP_STRUCT * tp, EmcPose end,
		PmCartesian center, PmCartesian normal, int turn, int type,
                double vel, double ini_maxvel, double acc, unsigned char enables, char atspeed)
{
    TC_STRUCT tc;
    PmCircle circle;
    PmLine line_uvw, line_abc;
    PmPose start_xyz, end_xyz;
    PmPose start_uvw, end_uvw;
    PmPose start_abc, end_abc;
    double helix_z_component;   // z of the helix's cylindrical coord system
    double helix_length;
    PmQuaternion identity_quat = { 1.0, 0.0, 0.0, 0.0 };

    if (!tp || tp->aborting) 
	return -1;

    start_xyz.tran = tp->goalPos.tran;
    end_xyz.tran = end.tran;

    start_abc.tran.x = tp->goalPos.a;
    start_abc.tran.y = tp->goalPos.b;
    start_abc.tran.z = tp->goalPos.c;
    end_abc.tran.x = end.a;
    end_abc.tran.y = end.b;
    end_abc.tran.z = end.c;

    start_uvw.tran.x = tp->goalPos.u;
    start_uvw.tran.y = tp->goalPos.v;
    start_uvw.tran.z = tp->goalPos.w;
    end_uvw.tran.x = end.u;
    end_uvw.tran.y = end.v;
    end_uvw.tran.z = end.w;

    start_xyz.rot = identity_quat;
    end_xyz.rot = identity_quat;
    start_uvw.rot = identity_quat;
    end_uvw.rot = identity_quat;
    start_abc.rot = identity_quat;
    end_abc.rot = identity_quat;

    pmCircleInit(&circle, start_xyz, end_xyz, center, normal, turn);
    pmLineInit(&line_uvw, start_uvw, end_uvw);
    pmLineInit(&line_abc, start_abc, end_abc);

    // find helix length
    pmCartMag(circle.rHelix, &helix_z_component);
    helix_length = pmSqrt(pmSq(circle.angle * circle.radius) +
                          pmSq(helix_z_component));

    tc.sync_accel = 0;
    tc.cycle_time = tp->cycleTime;
    tc.target = helix_length;
    tc.progress = 0.0;
    tc.reqvel = vel;
    tc.maxaccel = acc;
    tc.feed_override = 0.0;
    tc.maxvel = ini_maxvel;
    tc.id = tp->nextId;
    tc.active = 0;
    tc.atspeed = atspeed;

    tc.currentvel = 0.0;
    tc.blending = 0;
    tc.blend_vel = 0.0;
    tc.vel_at_blend_start = 0.0;

    tc.coords.circle.xyz = circle;
    tc.coords.circle.uvw = line_uvw;
    tc.coords.circle.abc = line_abc;
    tc.motion_type = TC_CIRCULAR;
    tc.canon_motion_type = type;
    tc.blend_with_next = tp->termCond == TC_TERM_COND_BLEND;
    tc.tolerance = tp->tolerance;

    tc.synchronized = tp->synchronized;
    tc.velocity_mode = tp->velocity_mode;
    tc.uu_per_rev = tp->uu_per_rev;
    tc.enables = enables;
    tc.indexrotary = -1;
    
    if (syncdio.anychanged != 0) {
	tc.syncdio = syncdio; //enqueue the list of DIOs that need toggling
	tpClearDIOs(); // clear out the list, in order to prepare for the next time we need to use it
    } else {
	tc.syncdio.anychanged = 0;
    }


    if (tcqPut(&tp->queue, tc) == -1) {
	return -1;
    }

    tp->goalPos = end;
    tp->done = 0;
    tp->depth = tcqLen(&tp->queue);
    tp->nextId++;

    return 0;
}
コード例 #22
0
ファイル: _posemath.c プロジェクト: 13788593535/machinekit
/** Find square of magnitude of a vector (useful for some calculations to save a sqrt).*/
int pmCartMagSq(PmCartesian const * const v, double *d)
{
    *d = pmSq(v->x) + pmSq(v->y) + pmSq(v->z);

    return pmErrno = 0;
}
コード例 #23
0
ファイル: _posemath.c プロジェクト: 13788593535/machinekit
int pmCartIsNorm(PmCartesian const * const v)
{
    return pmSqrt(pmSq(v->x) + pmSq(v->y) + pmSq(v->z)) - 1.0 < UNIT_VEC_FUZZ ? 1 : 0;
}
コード例 #24
0
ファイル: tc.c プロジェクト: CNCBASHER/linuxcnc
EmcPose tcGetPosReal(TC_STRUCT * tc, int of_endpoint)
{
    EmcPose pos;
    PmPose xyz;
    PmPose abc;
    PmPose uvw;
    
    double progress = of_endpoint? tc->target: tc->progress;
#if(TRACE != 0)
    static double last_l, last_u,last_x = 0 , last_y = 0, last_z = 0, last_a = 0;
#endif

    if (tc->motion_type == TC_RIGIDTAP) {
        if(tc->coords.rigidtap.state > REVERSING) {
            pmLinePoint(&tc->coords.rigidtap.aux_xyz, progress, &xyz);
        } else {
            pmLinePoint(&tc->coords.rigidtap.xyz, progress, &xyz);
        }
        // no rotary move allowed while tapping
        abc.tran = tc->coords.rigidtap.abc;
        uvw.tran = tc->coords.rigidtap.uvw;
    } else if (tc->motion_type == TC_LINEAR) {

        if (tc->coords.line.xyz.tmag > 0.) {
            // progress is along xyz, so uvw and abc move proportionally in order
            // to end at the same time.
            pmLinePoint(&tc->coords.line.xyz, progress, &xyz);
            pmLinePoint(&tc->coords.line.uvw,
                        progress * tc->coords.line.uvw.tmag / tc->target,
                        &uvw);
            pmLinePoint(&tc->coords.line.abc,
                        progress * tc->coords.line.abc.tmag / tc->target,
                        &abc);
        } else if (tc->coords.line.uvw.tmag > 0.) {
            // xyz is not moving
            pmLinePoint(&tc->coords.line.xyz, 0.0, &xyz);
            pmLinePoint(&tc->coords.line.uvw, progress, &uvw);
            // abc moves proportionally in order to end at the same time
            pmLinePoint(&tc->coords.line.abc,
                        progress * tc->coords.line.abc.tmag / tc->target,
                        &abc);
        } else {
            // if all else fails, it's along abc only
            pmLinePoint(&tc->coords.line.xyz, 0.0, &xyz);
            pmLinePoint(&tc->coords.line.uvw, 0.0, &uvw);
            pmLinePoint(&tc->coords.line.abc, progress, &abc);
        }
    } else if (tc->motion_type == TC_CIRCULAR) {//we have TC_CIRCULAR
        // progress is always along the xyz circle.  This simplification
        // is possible since zero-radius arcs are not allowed by the interp.

        pmCirclePoint(&tc->coords.circle.xyz,
                      progress * tc->coords.circle.xyz.angle / tc->target,
                      &xyz);
        // abc moves proportionally in order to end at the same time as the
        // circular xyz move.
        pmLinePoint(&tc->coords.circle.abc,
                    progress * tc->coords.circle.abc.tmag / tc->target,
                    &abc);
        // same for uvw
        pmLinePoint(&tc->coords.circle.uvw,
                    progress * tc->coords.circle.uvw.tmag / tc->target,
                    &uvw);

    } else {
        int s, tmp1,i;
        double       u,*N,R, X, Y, Z, A, B, C, U, V, W, F, D;
        double       curve_accel;
#if(TRACE != 0)
        double delta_l, delta_u, delta_d, delta_x, delta_y, delta_z, delta_a;
#endif
        N = tc->nurbs_block.N;
//        NL = tc->nurbs_block.NL;
        assert(tc->motion_type == TC_NURBS);

        u = progress / tc->target;
        if (u<1) {

            s = nurbs_findspan(tc->nurbs_block.nr_of_ctrl_pts-1,  tc->nurbs_block.order - 1,
                                u, tc->nurbs_block.knots_ptr);  //return span index of u_i
            nurbs_basisfun(s, u, tc->nurbs_block.order - 1 , tc->nurbs_block.knots_ptr , N);    // input: s:knot span index u:u_0 d:B-Spline degree  k:Knots
                           // output: N:basis functions
            // refer to bspeval.cc::line(70) of octave
            // refer to opennurbs_evaluate_nurbs.cpp::line(985) of openNurbs
            // refer to ON_NurbsCurve::Evaluate() for ...
            // refer to opennurbs_knot.cpp::ON_NurbsSpanIndex()
            // http://www.rhino3d.com/nurbs.htm (What is NURBS?)
            //    Some modelers that use older algorithms for NURBS
            //    evaluation require two extra knot values for a total of
            //    degree+N+1 knots. When Rhino is exporting and importing
            //    NURBS geometry, it automatically adds and removes these
            //    two superfluous knots as the situation requires.
            tmp1 = s - tc->nurbs_block.order + 1;
            assert(tmp1 >= 0);
            assert(tmp1 < tc->nurbs_block.nr_of_ctrl_pts);

            R = 0.0;
            for (i=0; i<=tc->nurbs_block.order -1 ; i++) {

                R += N[i]*tc->nurbs_block.ctrl_pts_ptr[tmp1+i].R;
            }

            X = 0.0;
            for (i=0; i<=tc->nurbs_block.order -1; i++) {
                    X += N[i]*tc->nurbs_block.ctrl_pts_ptr[tmp1+i].X;

            }
            X = X/R;
            xyz.tran.x = X;

            Y = 0.0;
            for (i=0; i<=tc->nurbs_block.order -1; i++) {
                    Y += N[i]*tc->nurbs_block.ctrl_pts_ptr[tmp1+i].Y;
            }
            Y = Y/R;
            xyz.tran.y = Y;

            Z = 0.0;
            for (i=0; i<=tc->nurbs_block.order -1; i++) {
                    Z += N[i]*tc->nurbs_block.ctrl_pts_ptr[tmp1+i].Z;
            }
            Z = Z/R;
            xyz.tran.z = Z;

            A = 0.0;
            for (i=0; i<=tc->nurbs_block.order -1; i++) {
                    A += N[i]*tc->nurbs_block.ctrl_pts_ptr[tmp1+i].A;
            }
            A = A/R;
            abc.tran.x = A;

            B = 0.0;
            for (i=0; i<=tc->nurbs_block.order -1; i++) {
                    B += N[i]*tc->nurbs_block.ctrl_pts_ptr[tmp1+i].B;
            }
            B = B/R;
            abc.tran.y = B;

            C = 0.0;
            for (i=0; i<=tc->nurbs_block.order -1; i++) {
                    C += N[i]*tc->nurbs_block.ctrl_pts_ptr[tmp1+i].C;
            }
            C = C/R;
            abc.tran.z = C;

            U = 0.0;
            for (i=0; i<=tc->nurbs_block.order -1; i++) {
                    U += N[i]*tc->nurbs_block.ctrl_pts_ptr[tmp1+i].U;
            }
            U = U/R;
            uvw.tran.x = U;

            V = 0.0;
            for (i=0; i<=tc->nurbs_block.order -1; i++) {
                    V += N[i]*tc->nurbs_block.ctrl_pts_ptr[tmp1+i].V;
            }
            V = V/R;
            uvw.tran.y = V;

            W = 0.0;
            for (i=0; i<=tc->nurbs_block.order -1; i++) {
                    W += N[i]*tc->nurbs_block.ctrl_pts_ptr[tmp1+i].W;
            }
            W = W/R;
            uvw.tran.z = W;

            F = 0.0;
            F = tc->nurbs_block.ctrl_pts_ptr[tmp1].F;
            tc->reqvel = F;

            D = 0.0;
            for (i=0; i<=tc->nurbs_block.order -1; i++) {
                    D += N[i]*tc->nurbs_block.ctrl_pts_ptr[tmp1+i].D;
            }
            D = D/R;

            // compute allowed feed
            if(!of_endpoint) {
                curve_accel = (tc->cur_vel * tc->cur_vel)/D;
                if(curve_accel > tc->maxaccel) {
                    // modify req_vel
                    tc->reqvel = pmSqrt((tc->maxaccel * D));
                }
            }

#if (TRACE != 0)
                if(l == 0 && _dt == 0) {
                    last_l = 0;
                    last_u = 0;
                    last_x = xyz.tran.x;
                    last_y = xyz.tran.y;
                    last_z = xyz.tran.z;
                    last_a = 0;
                    _dt+=1;
                }
                delta_l = l - last_l;
                last_l = l;
                delta_u = u - last_u;
                last_u = u;
                delta_x = xyz.tran.x - last_x;
                delta_y = xyz.tran.y - last_y;
                delta_z = xyz.tran.z - last_z;
                delta_a = abc.tran.x - last_a;
                delta_d = pmSqrt(pmSq(delta_x)+pmSq(delta_y)+pmSq(delta_z));
                last_x = xyz.tran.x;
                last_y = xyz.tran.y;
                last_z = xyz.tran.z;
                last_a = abc.tran.x;
                if( delta_d > 0)
                {
                    if(_dt == 1){
                      /* prepare header for gnuplot */
                        DPS ("%11s%15s%15s%15s%15s%15s%15s%15s%15s\n",
                           "#dt", "u", "l","x","y","z","delta_d", "delta_l","a");
                    }

                    DPS("%11u%15.10f%15.10f%15.5f%15.5f%15.5f%15.5f%15.5f%15.5f\n",
                           _dt, u, l,last_x, last_y, last_z, delta_d, delta_l, last_a);

                    _dt+=1;
                }
#endif // (TRACE != 0)

        }else {
            xyz.tran.x = tc->nurbs_block.ctrl_pts_ptr[tc->nurbs_block.nr_of_ctrl_pts-1].X;
            xyz.tran.y = tc->nurbs_block.ctrl_pts_ptr[tc->nurbs_block.nr_of_ctrl_pts-1].Y;
            xyz.tran.z = tc->nurbs_block.ctrl_pts_ptr[tc->nurbs_block.nr_of_ctrl_pts-1].Z;
            uvw.tran.x = tc->nurbs_block.ctrl_pts_ptr[tc->nurbs_block.nr_of_ctrl_pts-1].U;
            uvw.tran.y = tc->nurbs_block.ctrl_pts_ptr[tc->nurbs_block.nr_of_ctrl_pts-1].V;
            uvw.tran.z = tc->nurbs_block.ctrl_pts_ptr[tc->nurbs_block.nr_of_ctrl_pts-1].W;
            abc.tran.x = tc->nurbs_block.ctrl_pts_ptr[tc->nurbs_block.nr_of_ctrl_pts-1].A;
            abc.tran.y = tc->nurbs_block.ctrl_pts_ptr[tc->nurbs_block.nr_of_ctrl_pts-1].B;
            abc.tran.z = tc->nurbs_block.ctrl_pts_ptr[tc->nurbs_block.nr_of_ctrl_pts-1].C;
           // R = tc->nurbs_block.ctrl_pts_ptr[tc->nurbs_block.nr_of_ctrl_pts-1].R;
        }
    }
    //DP ("GetEndPoint?(%d) R(%.2f) X(%.2f) Y(%.2f) Z(%.2f) A(%.2f)\n",of_endpoint, R, X, Y, Z, A);
    // TODO-eric if R going to show ?
//#if (TRACE != 0)
//    if(_dt == 0){
//        /* prepare header for gnuplot */
//        DPS ("%11s%15s%15s%15s\n", "#dt", "x", "y", "z");
//    }
//    DPS("%11u%15.5f%15.5f%15.5f\n", _dt, xyz.tran.x, xyz.tran.y, xyz.tran.z);
//    _dt+=1;
//#endif // (TRACE != 0)
#if (TRACE != 1)
    if( of_endpoint != 1) {

    }
#endif
    pos.tran = xyz.tran;
    pos.a = abc.tran.x;
    pos.b = abc.tran.y;
    pos.c = abc.tran.z;
    pos.u = uvw.tran.x;
    pos.v = uvw.tran.y;
    pos.w = uvw.tran.z;
//    DP ("GetEndPoint?(%d) tc->id %d MotionType %d X(%.2f) Y(%.2f) Z(%.2f) A(%.2f)\n",
//    		of_endpoint,tc->id,tc->motion_type, pos.tran.x,
//    		pos.tran.y, pos.tran.z, pos.a);
    return pos;
}
コード例 #25
0
ファイル: _posemath.c プロジェクト: 13788593535/machinekit
int pmQuatIsNorm(PmQuaternion const * const q1)
{
    return (rtapi_fabs(pmSq(q1->s) + pmSq(q1->x) + pmSq(q1->y) + pmSq(q1->z) - 1.0) <
	UNIT_QUAT_FUZZ);
}