On the arc interpolation algorithm for linuxcnc source code

More
27 Aug 2023 15:48 #279095 by lqb
Hi everyone!  I have recently been reading linuxcnc source code to learn how circular arc interpolation is implemented in linuxcnc. I would like to know which interpolation method is used in linuxcnc circular interpolation algorithm, and I would like to study it in conjunction with related sources so that it will be easier to understand.

Thank you, everyone!

int tpAddCircle(TP_STRUCT * const tp,
        EmcPose end,
        PmCartesian center,
        PmCartesian normal,
        int turn,
        int canon_motion_type,
        double vel,
        double ini_maxvel,
        double acc,
        unsigned char enables,
        char atspeed,
        struct state_tag_t tag)
{
    if (tpErrorCheck(tp)<0) {
        return TP_ERR_FAIL;
    }

    tp_info_print("== AddCircle ==\n");
    tp_debug_print("ini_maxvel = %f\n",ini_maxvel);

    TC_STRUCT tc = {0};

    /**
     * 使用通用参数初始化一个新的轨迹段。
     *
     * 注意:此函数只设置非零的默认值。请确保
     * 在调用此函数之前,结构体已正确初始化。
     */
    tcInit(&tc,
            TC_CIRCULAR,
            canon_motion_type,
            tp->cycleTime,
            enables,
            atspeed);
    
    tc.tag = tag;
    
    // Setup any synced IO for this move
    // 为本次移动设置任何同步 IO
    tpSetupSyncedIO(tp, &tc);

    // Copy over state data from the trajectory planner
    // 从轨迹规划器复制状态数据
    tcSetupState(&tc, tp);

    // Setup circle geometry
    // 设置圆的几何形状
    int res_init = pmCircle9Init(&tc.coords.circle,
            &tp->goalPos,
            &end,
            &center,
            &normal,
            turn);

    if (res_init) return res_init;

    // Update tc target with existing circular segment
    // 利用现有的环形线段更新 tc 目标
    tc.target = pmCircle9Target(&tc.coords.circle);
    if (tc.target < TP_POS_EPSILON) {
        return TP_ERR_ZERO_LENGTH;
    }
    
    tp_debug_print("tc.target = %f\n",tc.target);
    tc.nominal_length = tc.target;

    // Copy in motion parameters
    // 复制运动参数
    tcSetupMotion(&tc,
            vel,
            ini_maxvel,
            acc);

    //Reduce max velocity to match sample rate
    //降低最大速度以匹配采样率
    tcClampVelocityByLength(&tc);

    // 获取队列中最后一个 TC 元素,但不删除它
    TC_STRUCT *prev_tc;
    prev_tc = tcqLast(&tp->queue);

    // 改变处理模式
    handleModeChange(prev_tc, &tc);
    if (emcmotConfig->arcBlendEnable){
        tpHandleBlendArc(tp, &tc);
        findSpiralArcLengthFit(&tc.coords.circle.xyz, &tc.coords.circle.fit);
    }
    
    tcFinalizeLength(prev_tc);
    tcFlagEarlyStop(prev_tc, &tc);

    int retval = tpAddSegmentToQueue(tp, &tc, true);

    tpRunOptimization(tp);
    return retval;
}
 
Attachments:

Please Log in or Create an account to join the conversation.

More
28 Aug 2023 11:18 #279151 by rmu
Points on circles are calculated with sin/cos and not interpolated. Relevant code in pmCirclePoint in file _posemath.c
The following user(s) said Thank You: Aciera, lqb

Please Log in or Create an account to join the conversation.

Time to create page: 0.102 seconds
Powered by Kunena Forum