tp.c
来自「CNC 的开放码,EMC2 V2.2.8版」· C语言 代码 · 共 1,046 行 · 第 1/3 页
C
1,046 行
} if(tc->active == 0) { // this means this tc is being read for the first time. tc->currentvel = 0; tp->depth = tp->activeDepth = 1; tp->motionType = tc->canon_motion_type; tc->active = 1; tc->blending = 0; // clamp motion's velocity at TRAJ MAX_VELOCITY (tooltip maxvel) if(tc->maxvel > tp->vLimit) tc->maxvel = tp->vLimit; // honor accel constraint in case we happen to make an acute angle // with the next segment. if(tc->blend_with_next) tc->maxaccel /= 2.0; if(tc->synchronized) { if(!tc->velocity_mode && !emcmotStatus->spindleSync) { // if we aren't already synced, wait waiting = tc->id; // ask for an index reset emcmotStatus->spindle_index_enable = 1; spindleoffset = 0.0; // don't move: wait return 0; } } } if(nexttc && nexttc->active == 0) { // this means this tc is being read for the first time. nexttc->currentvel = 0; tp->depth = tp->activeDepth = 1; nexttc->active = 1; nexttc->blending = 0; // clamp motion's velocity at TRAJ MAX_VELOCITY (tooltip maxvel) if(nexttc->maxvel > tp->vLimit) nexttc->maxvel = tp->vLimit; // honor accel constraint if we happen to make an acute angle with the // above segment or the following one if(tc->blend_with_next || nexttc->blend_with_next) nexttc->maxaccel /= 2.0; } if(tp->aborting) { // an abort message has come if( (tc->currentvel == 0.0 && !nexttc) || (tc->currentvel == 0.0 && nexttc && nexttc->currentvel == 0.0) ) { tcqInit(&tp->queue); tp->goalPos = tp->currentPos; tp->done = 1; tp->depth = tp->activeDepth = 0; tp->aborting = 0; tp->execId = 0; tp->motionType = 0; tp->synchronized = 0; emcmotStatus->spindleSync = 0; tpResume(tp); return 0; } else { tc->reqvel = 0.0; if(nexttc) nexttc->reqvel = 0.0; } } if(tc->synchronized) { double revs; double pos_error; if(tc->velocity_mode) { pos_error = emcmotStatus->spindleSpeedIn * tc->uu_per_rev; if(nexttc) pos_error -= nexttc->progress; /* ?? */ if(!tp->aborting) tc->reqvel = pos_error; } else { if(tc->motion_type == TC_RIGIDTAP && (tc->coords.rigidtap.state == RETRACTION || tc->coords.rigidtap.state == FINAL_REVERSAL)) revs = tc->coords.rigidtap.spindlerevs_at_reversal - emcmotStatus->spindleRevs; else revs = emcmotStatus->spindleRevs; pos_error = (revs - spindleoffset) * tc->uu_per_rev - tc->progress; if(nexttc) pos_error -= nexttc->progress; tc->reqvel = pos_error/tc->cycle_time/2.0; } tc->feed_override = 1.0; if(tc->reqvel < 0.0) tc->reqvel = 0.0; if(nexttc) { if (nexttc->synchronized) { nexttc->reqvel = pos_error/nexttc->cycle_time; nexttc->feed_override = 1.0; if(nexttc->reqvel < 0.0) nexttc->reqvel = 0.0; } else { nexttc->feed_override = emcmotStatus->net_feed_scale; } } } else { tc->feed_override = emcmotStatus->net_feed_scale; if(nexttc) { nexttc->feed_override = emcmotStatus->net_feed_scale; } } /* handle pausing */ if(tp->pausing && !tc->synchronized) { tc->feed_override = 0.0; if(nexttc) { nexttc->feed_override = 0.0; } } // calculate the approximate peak velocity the nexttc will hit. // we know to start blending it in when the current tc goes below // this velocity... if(nexttc && nexttc->maxaccel) { tc->blend_vel = nexttc->maxaccel * pmSqrt(nexttc->target / nexttc->maxaccel); if(tc->blend_vel > nexttc->reqvel * nexttc->feed_override) { // segment has a cruise phase so let's blend over the // whole accel period if possible tc->blend_vel = nexttc->reqvel * nexttc->feed_override; } if(tc->maxaccel < nexttc->maxaccel) tc->blend_vel *= tc->maxaccel/nexttc->maxaccel; if(tc->tolerance) { /* see diagram blend.fig. T (blend tolerance) is given, theta * is calculated from dot(s1,s2) * * blend criteria: we are decelerating at the end of segment s1 * and we pass distance d from the end. * find the corresponding velocity v when passing d. * * in the drawing note d = 2T/cos(theta) * * when v1 is decelerating at a to stop, v = at, t = v/a * so required d = .5 a (v/a)^2 * * equate the two expressions for d and solve for v */ double tblend_vel; double dot; double theta; PmCartesian v1, v2; v1 = tcGetEndingUnitVector(tc); v2 = tcGetStartingUnitVector(nexttc); pmCartCartDot(v1, v2, &dot); theta = acos(-dot)/2.0; if(cos(theta) > 0.001) { tblend_vel = 2.0 * pmSqrt(tc->maxaccel * tc->tolerance / cos(theta)); if(tblend_vel < tc->blend_vel) tc->blend_vel = tblend_vel; } } } primary_before = tcGetPos(tc); tcRunCycle(tc, &primary_vel, &on_final_decel); primary_after = tcGetPos(tc); pmCartCartSub(primary_after.tran, primary_before.tran, &primary_displacement.tran); primary_displacement.a = primary_after.a - primary_before.a; primary_displacement.b = primary_after.b - primary_before.b; primary_displacement.c = primary_after.c - primary_before.c; primary_displacement.u = primary_after.u - primary_before.u; primary_displacement.v = primary_after.v - primary_before.v; primary_displacement.w = primary_after.w - primary_before.w; // blend criteria if((tc->blending && nexttc) || (nexttc && on_final_decel && primary_vel < tc->blend_vel)) { // make sure we continue to blend this segment even when its // accel reaches 0 (at the very end) tc->blending = 1; // hack to show blends in axis // tp->motionType = 0; if(tc->currentvel > nexttc->currentvel) { tp->motionType = tc->canon_motion_type; emcmotStatus->distance_to_go = tc->target - tc->progress; emcmotStatus->enables_queued = tc->enables; // report our line number to the guis tp->execId = tc->id; } else { tp->motionType = nexttc->canon_motion_type; emcmotStatus->distance_to_go = nexttc->target - nexttc->progress; emcmotStatus->enables_queued = nexttc->enables; // report our line number to the guis tp->execId = nexttc->id; } emcmotStatus->current_vel = tc->currentvel + nexttc->currentvel; secondary_before = tcGetPos(nexttc); save_vel = nexttc->reqvel; nexttc->reqvel = nexttc->feed_override > 0.0 ? ((tc->vel_at_blend_start - primary_vel) / nexttc->feed_override) : 0.0; tcRunCycle(nexttc, NULL, NULL); nexttc->reqvel = save_vel; secondary_after = tcGetPos(nexttc); pmCartCartSub(secondary_after.tran, secondary_before.tran, &secondary_displacement.tran); secondary_displacement.a = secondary_after.a - secondary_before.a; secondary_displacement.b = secondary_after.b - secondary_before.b; secondary_displacement.c = secondary_after.c - secondary_before.c; secondary_displacement.u = secondary_after.u - secondary_before.u; secondary_displacement.v = secondary_after.v - secondary_before.v; secondary_displacement.w = secondary_after.w - secondary_before.w; pmCartCartAdd(tp->currentPos.tran, primary_displacement.tran, &tp->currentPos.tran); pmCartCartAdd(tp->currentPos.tran, secondary_displacement.tran, &tp->currentPos.tran); tp->currentPos.a += primary_displacement.a + secondary_displacement.a; tp->currentPos.b += primary_displacement.b + secondary_displacement.b; tp->currentPos.c += primary_displacement.c + secondary_displacement.c; tp->currentPos.u += primary_displacement.u + secondary_displacement.u; tp->currentPos.v += primary_displacement.v + secondary_displacement.v; tp->currentPos.w += primary_displacement.w + secondary_displacement.w; } else { tp->motionType = tc->canon_motion_type; emcmotStatus->distance_to_go = tc->target - tc->progress; tp->currentPos = primary_after; emcmotStatus->current_vel = tc->currentvel; emcmotStatus->enables_queued = tc->enables; // report our line number to the guis tp->execId = tc->id; } return 0;}int tpSetSpindleSync(TP_STRUCT * tp, double sync, int mode) { if(sync) { tp->synchronized = 1; tp->uu_per_rev = sync; tp->velocity_mode = mode; } else tp->synchronized = 0; return 0;}int tpPause(TP_STRUCT * tp){ if (0 == tp) { return -1; } tp->pausing = 1; return 0;}int tpResume(TP_STRUCT * tp){ if (0 == tp) { return -1; } tp->pausing = 0; return 0;}int tpAbort(TP_STRUCT * tp){ if (0 == tp) { return -1; } if (!tp->aborting) { /* to abort, signal a pause and set our abort flag */ tpPause(tp); tp->aborting = 1; } return 0;}int tpGetMotionType(TP_STRUCT * tp){ return tp->motionType;}EmcPose tpGetPos(TP_STRUCT * tp){ EmcPose retval; if (0 == tp) { retval.tran.x = retval.tran.y = retval.tran.z = 0.0; retval.a = retval.b = retval.c = 0.0; retval.u = retval.v = retval.w = 0.0; return retval; } return tp->currentPos;}int tpIsDone(TP_STRUCT * tp){ if (0 == tp) { return 0; } return tp->done;}int tpQueueDepth(TP_STRUCT * tp){ if (0 == tp) { return 0; } return tp->depth;}int tpActiveDepth(TP_STRUCT * tp){ if (0 == tp) { return 0; } return tp->activeDepth;}int tpSetAout(TP_STRUCT *tp, unsigned char index, double start, double end) { return 0;}int tpSetDout(TP_STRUCT *tp, int index, unsigned char start, unsigned char end) { return 0;}// vim:sw=4:sts=4:et:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?