ramlife

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

转自: https://blog.csdn.net/Renjiankun/article/details/80555251

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Renjiankun/article/details/80555251
        声明:本博客文档均由我本人编写,如需转载请先联系我。

在marlin固件中借鉴了Bresenham法,转化为了步进电机多轴联动算法,这个太厉害了。。。

回归正题,现在我知道了多轴联动可以使用bresham法转化过来,并且由Marlin固件源码作为参考,那么我们先来学习理论吧。。。基础知识。。。这个,会加减乘除,直线的一些定理都能算了。

Bresenham算法

直接贴理论吧,原理不难理解,大家可以自己演算一下。

以上就是Bresenham算法的推导过程,大家可以自己演算,我觉得自己再算过一遍会更踏实一些,好,理论推导完毕,怎么应用到联动控制里边呢?

那我们先要确定出X的值,所有轴的步数都是相当于Y就可以了,比如一个3轴,我x轴输出30,y轴输出20,z轴输出10,则选取最大的步数值作为X,则所有的轴都是Y,即转化到bresenham当中为3条直线,其中初始位置都是(0,0),x轴对应的坐标为(30,30),y轴对应的坐标为(30,20),z轴对应的坐标为(30,10),则各自的ΔY就是本身输入的步数,ΔX都是最大步数30。

我们变换一下想法,为了减少计算量,我们将所有的公式左右两边都除以2(程序中只需要右移>>1).则只要Pi还是小于零, Pi+1 = Pi + ΔY

若Pi > 0   Pi+1 = Pi + ΔY - ΔX,

相信聪明的小伙伴一经发现了 Pi +ΔY 只用算一遍就够了,只有在Pi > 0 的情况下 再减去ΔX就可以了。

需要注意的是P1 =  ΔY - ΔX/2,

从marlin固件中提取出了多轴breshenham算法如下:采用Arduino Uno(ATMega328)实现例程控制3轴联动如下:

int step_even_count; // 步数计数
int step_x,step_y,step_z; //各轴输出的步数 ΔY
int count_x,count_y,count_z;//各轴的Pi
int step_completed;//步数计数器
 
void setup() {
step_x=1600;
step_y=800;
step_z=400;
step_even_count = max(step_x,step_y);
step_even_count = max(step_z,step_even_count);//取各轴最大值作为X(ΔX)
count_x = -(step_even_count>>1);//-ΔX/2  ΔX➗2,后边所有数据都是除2处理 
count_y = count_x;
count_z = count_x;
 
 
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
pinMode(8,OUTPUT);
pinMode(9,OUTPUT);
digitalWrite(2,1);
digitalWrite(8,1);
Serial.begin(9600);
}
 
 
 
void loop() {
  // put your main code here, to run repeatedly:
  // ΔX都是一致的
  // < 0 Pi + ΔY
  // > 0 Pi + ΔY - ΔX
  //并且应该注意到 P1 = ΔY - ΔX/2
  while(step_completed<step_even_count)
  {
      count_x+=step_x;  //计算小于0 的情况 = Pi + ΔY
      if(count_x>0)		//Pi >0
      {
        digitalWrite(3,1);		  //输出一个脉冲
        count_x-=step_even_count; //由于Pi + ΔY已经计算,此处直接减去ΔX即可
        digitalWrite(3,0);
        }
 
         count_y+=step_y;
      if(count_y>0)
      {
        digitalWrite(9,1);
        count_y-=step_even_count;
        digitalWrite(9,0);
        }
 
       count_z+=step_z;
      if(count_z>0)
      {
        digitalWrite(10,1);
        count_z-=step_even_count;
        digitalWrite(10,0);
        }
   step_completed+=1;
   delayMicroseconds(300);//脉冲间隔
    }
   while(1);
}

好吧,这就是Marlin固件中的多轴联动控制了,能想到这样控制的人真厉害,我也只是重新推导了而已。顺便一提,该算法实际上在直角坐标系机器人上可用作直线插补算法,而在连杆型机器人上用作多轴联动。

大家多留言评论一下给我点创作的动力,后面还有好多详细的算法还会分享,都是经过本人从理论论证到实践使用的算法。或者直接和我交流共同进步。

————————————————
版权声明:本文为CSDN博主「Renjiankun」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Renjiankun/article/details/80555251

posted on 2019-11-28 00:51  ramlife  阅读(847)  评论(0编辑  收藏  举报