开源改变世界

关于ARC插值的小建议 #756

推推 grbl 3年前 (2023-01-22) 87次浏览

关闭
blunsmith 打开了这个问题 2015 年 7 月 5 日 · 3条评论
关闭

关于ARC插值的小建议#756

blunsmith 打开了这个问题 2015 年 7 月 5 日 · 3条评论

注释

关于ARC插值的小建议 #756

我做了一个CNC控制器,我用的是TI的MSP430F5438A微处理器。仔细看看你的代码。给了我一些启发,非常感谢,不过我不想从ARDUINO做MSP430的移植。于是自己写了一个controller,看了你的一个ARC插值算法,个人感觉不是很完美,建议你用积分形式的算法更好,这样可以获得更高的精度。对于线性插值部分,因为我的英文很差,所以看的不是太清楚。
因为我想做六轴机,所以我觉得这个直线插补控制对我来说太重要了。我还使用了线性插值积分形式。积分,后面有时间我会解释的很详细。积分以为我借用了GUI中显示的很多图形函数。
最好的祝愿

关于ARC插值的小建议 #756
成员

@blunsmith: 对不起,我很难理解你在说什么。arc 实现非常好,用于补偿 8 位 AVR 上三角函数计算的缓慢程度。如果您进行数学计算并查看错误,它的准确度绝不会低于 CNC 机床的物理精度。换句话说,为 sin() 和 cos() 计算计算更高的精度不会改进圆弧插值。

关于ARC插值的小建议 #756

对不起,我没有表达清楚。这是我的mc_line()的一部分。
mcu: MSP430F5438A 16bit
soft :IAR 5.30

//采用积分方式的六轴联动方案程序
void step_line(unsigned long* target,float feed_rate)
{
unsigned long xerr=0,yerr=0,zerr=0,aerr=0,berr=0,cerr=0,distance ;
unsigned long container;//积分所用到的容器

 distance=(long)fmax(fmax(fmax(target[X_AXIS],target[Y_AXIS]),target[Z_AXIS]),fmax(fmax(target[X_AXIS],target[Y_AXIS]),target[C_AXIS]));  //选取基本增量坐标轴 
 container=distance;       //选用最大值作为容器,容器值可以更大,但要求更高的处理器速度。

 for(long t=0;t<=distance;t++)  //画线输出  第一次进入循环的时
{//积分累加
    xerr+=target[X_AXIS];  
    yerr+=target[Y_AXIS];
    zerr+=target[Z_AXIS];
    aerr+=target[A_AXIS];
    berr+=target[B_AXIS];
    cerr+=target[C_AXIS];
    delay_ms(1);
    serial_send_coord(gc_state.position_mm);//发送当前坐标值
    if(xerr>container)  //积分值判断输出
    {   
        xerr-=container;   
        if(Pin_PUL_OUT & X_AXIS_PUL) { Pin_PUL_OUT &= ~X_AXIS_PUL;} else {Pin_PUL_OUT |= X_AXIS_PUL;}
        //计算当前坐标值
        gc_state.position[X_AXIS] += motor_deriction[X_AXIS];
        gc_state.position_mm[X_AXIS] = gc_state.position[X_AXIS]/steps_per_mm[X_AXIS];
    }  
    if(yerr>container)  
    {  
        yerr-=container;  
        if(Pin_PUL_OUT & Y_AXIS_PUL) { Pin_PUL_OUT &= ~Y_AXIS_PUL;} else {Pin_PUL_OUT |= Y_AXIS_PUL;}
        gc_state.position[Y_AXIS] += motor_deriction[Y_AXIS];
        gc_state.position_mm[Y_AXIS] = gc_state.position[Y_AXIS]/steps_per_mm[Y_AXIS];

    }  
    if(zerr>container)  
    {  
        zerr-=container;  
        if(Pin_PUL_OUT & Z_AXIS_PUL) { Pin_PUL_OUT &= ~Z_AXIS_PUL;} else {Pin_PUL_OUT |= Z_AXIS_PUL;}
        gc_state.position[Z_AXIS] += motor_deriction[Z_AXIS];   
        gc_state.position_mm[Z_AXIS] = gc_state.position[Z_AXIS]/steps_per_mm[Z_AXIS];
    }
    if(aerr>container)  
    {  
        aerr-=container;  
        if(Pin_PUL_OUT & A_AXIS_PUL) { Pin_PUL_OUT &= ~A_AXIS_PUL;} else {Pin_PUL_OUT |= A_AXIS_PUL;}
        gc_state.position[A_AXIS] += motor_deriction[A_AXIS];
        gc_state.position_mm[A_AXIS] = gc_state.position[A_AXIS]/steps_per_mm[A_AXIS];
    }
    if(berr>container)  
    {  
        berr-=container;  
        if(Pin_PUL_OUT & B_AXIS_PUL) { Pin_PUL_OUT &= ~B_AXIS_PUL;} else {Pin_PUL_OUT |= B_AXIS_PUL;}
        gc_state.position[B_AXIS] += motor_deriction[B_AXIS];
        gc_state.position_mm[B_AXIS] = gc_state.position[B_AXIS]/steps_per_mm[B_AXIS];
    }
    if(cerr>container)  
    {  
        cerr-=container;  
        if(Pin_PUL_OUT & C_AXIS_PUL) { Pin_PUL_OUT &= ~C_AXIS_PUL;} else {Pin_PUL_OUT |= C_AXIS_PUL;}
        gc_state.position[C_AXIS] += motor_deriction[C_AXIS];
        gc_state.position_mm[C_AXIS] = gc_state.position[C_AXIS]/steps_per_mm[C_AXIS];
    }
}

write_SegD(gc_state.position_mm);//把当前坐标值存入seg D

#ifdef DEBUG
delay_ms(feed_rate);
坐标初始化();//测式使用
#endif
}
#endif

我要上传图片,给你看。如何上传照片?

关于ARC插值的小建议 #756
成员

@blunsmith: 看来你说的是step段生成算法。你错了。它实际上是完美的,并且使用了中点法则,它精确地描绘了梯形轮廓。您提出的建议在计算上非常昂贵。每种方法都有不同之处,Arduino Uno 只能快速进行某些计算,除法不是其中之一。

喜欢 (0)