声明:本博客文档均由我本人编写,如需转载请先联系我。
在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_completed0) //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固件中的多轴联动控制了,能想到这样控制的人真厉害,我也只是重新推导了而已。顺便一提,该算法实际上在直角坐标系机器人上可用作直线插补算法,而在连杆型机器人上用作多轴联动。
大家多留言评论一下给我点创作的动力,后面还有好多详细的算法还会分享,都是经过本人从理论论证到实践使用的算法。或者直接和我交流共同进步。