您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > Delta(rostock型)3d打印机算法解读及调试步骤
Delta(rostock型)3d打印机算法解读及调试步骤一、前言Delta机型是一种并联式运动结构的3d打印机,delta机型实际上是分为两大类,一种是工业上用的并联式机器人;另外一种是rostock的运动结构。这两种结构做出来的打印机给人的感觉都是非常cool的。所以大伙都偏好这类型的打印机,目前主流的固件marlin和repetier都支持rostock结构的3d打印机。这里鸭哥就谈谈自己对rostock机型的运动算法的理解,继而从运动算法中推算一下如何调试一台rostock的参数。二、基础知识要理解rostock的全部运动算法所要涉及的数学知识不是太多,如果不记得的话,是时候找高中数学老师喝喝茶吃个小饭啦。1)三角函数sincos这个是理解rostock计算过程的基础知识2)笛卡尔空间坐标转换/线性代数,这个嘛是属于进阶内容,如果懂那就更好啦,如果不懂也没关系,在把所有的外界条件全部设置为理想情况下,这个笛卡尔空间坐标转换可以不用精通的。(包括鸭哥也不敢说对笛卡尔空间坐标转换和线性代数精通哦)3)marlin程序的结构逻辑结构(对于arduinoide/arduino程序基本教程,这里就不展开了,不懂的小白们可以先学一下arduino的基础教程先,饭要一口一口得出,路要一步一步的走)三、Marlin程序解读这里鸭哥不打算讲marlin的整个loop()函数的流程,讲讲delta机型的核心部分。对于marlin来说,delta机型和非delta机型在对于温控、看门狗、电机运动甚至空间坐标等方面都是一样的。区别在哪里呢?区别就在与delta多了一个笛卡尔坐标转换的函数Marlin的loop()主体流程Voidloop(){Get_command();//从sd卡或者串口获取gcodeProcess_command();//解析gcode并且执行代码Manage_heater();//控制机器的喷头和热床的温度Manage_inactivity();//checkHitEndstops();//检查endstop的状态Lcd_update();//更新lcd上面的信息}在这个过程中process_command()是控制的核心,各位仔细研读一下process_command()的代码就发现arduino的厉害了。简单说一下process_command()的流程,说白了,process_command()就是一个巨大的case结构,这里讲讲G1命令的大致逻辑(G1命令不知道的自己搜索去):Process_command(){Case0://g0-g1Case1:{if(Stopped==false){get_coordinates();//获取当前的坐标,这里是指打印件的世界坐标哦,不是delta的xyz电机的坐标哦!普通结构的打印机则是一样的。#ifdefFWRETRACTif(autoretract_enabled)if(!(code_seen('X')||code_seen('Y')||code_seen('Z'))&&code_seen('E')){//获取命令中xyze轴的参数Floatechange=destination[E_AXIS]-current_position[E_AXIS];//这里是算最小回抽值的,如果移动距离小于最小回抽值就不回抽了。这里是一个辅助功能。简单了解可以了。if((echange-MIN_RETRACT&&!retracted)||(echangeMIN_RETRACT&&retracted)){//moveappearstobeanattempttoretractorrecovercurrent_position[E_AXIS]=destination[E_AXIS];//hidetheslicer-generatedretract/recoverfromcalculationsplan_set_e_position(current_position[E_AXIS]);//ANDfromtheplannerretract(!retracted);return;}}#endif//FWRETRACTprepare_move();//执行移动命令return;}}从上面的代码来看呢,对于运动类的Gcode,marlin会在process_command()函数中获取xyze各轴的参数后算出目标坐标(destination[_AXIS]),也会使用get_coordinates()来获取当前坐标(current_position[E_AXIS])(再次强调,这个坐标是打印件的世界坐标),当我们知道了目标坐标和当前坐标以后,空间中移动的距离就可以算出来了(不会算的,请自觉请高中数学老师吃饭去),接下来marlin就使用perpare_move()来控制电机啦。接下来呢很自然就要讲讲prepare_move()这个函数啦。先上代码先,代码鸭哥做了精简,只看关键的部分就是delta和普通结构的代码,先说一下plan_buffer_line()这个函数的作用的把坐标数组current_position[i]、destination[i]放到一个内存的一个缓存区里面,然后控制电机转多少圈这样一个作用的,具体代码可以自己去看,在一旦进入这个函数以后,delta和普通机型的代码都是一样的,也就是说delta和普通结构的电机控制其实是一样的。Difference[i]数组:用来储存目标坐标和当前坐标之间的距离的,(这里是包含了xyze轴的数组)Destination[i]数组:目标坐标的数值,是从process_command()函数中G1读取XYZE参数获取的。Current_position[i]数组:当前坐标的数值,是从G1命令中get_coordinates()传递过来的。如果是3个轴都归零的情况下,current_position就是储存三个坐标原点,如果开始运动了,这里的值就是上一个prepare_move()循环执行后上一次的destination[i]的值。(这个下面会有看到赋值语句)Delta[i]数组:delta打印机的xyz三个电机要移动的距离voidprepare_move(){#ifdefDELTA//设置机子是delta机型(rostock)floatdifference[NUM_AXIS];//定义目标距离,用于转换坐标用的过渡变量for(int8_ti=0;iNUM_AXIS;i++){difference[i]=destination[i]-current_position[i];}//计算世界坐标的距离值//***开始计算笛卡尔距离并且暴力直线插值来减少运算量***//floatcartesian_mm=sqrt(sq(difference[X_AXIS])+sq(difference[Y_AXIS])+sq(difference[Z_AXIS]));if(cartesian_mm0.000001){cartesian_mm=abs(difference[E_AXIS]);}if(cartesian_mm0.000001){return;}floatseconds=6000*cartesian_mm/feedrate/feedmultiply;intsteps=max(1,int(delta_segments_per_second*seconds));for(ints=1;s=steps;s++){floatfraction=float(s)/float(steps);//直线插值for(int8_ti=0;iNUM_AXIS;i++){destination[i]=current_position[i]+difference[i]*fraction;}//***结束计算笛卡尔距离并且暴力直线插值来减少运算量***//calculate_delta(destination);//将打印件的世界坐标转换为xyz电机轴的运动量plan_buffer_line(delta[X_AXIS],delta[Y_AXIS],delta[Z_AXIS],destination[E_AXIS],feedrate*feedmultiply/60/100.0,active_extruder);}#endif//DELTA。。。。。。。。。。。。#if!(definedDELTA||definedSCARA)//DonotusefeedmultiplyforEorZonlymovesif((current_position[X_AXIS]==destination[X_AXIS])&&(current_position[Y_AXIS]==destination[Y_AXIS])){plan_buffer_line(destination[X_AXIS],destination[Y_AXIS],destination[Z_AXIS],destination[E_AXIS],feedrate/60,active_extruder);//直接将destination[i]的值发送去运动缓存里面}else{plan_buffer_line(destination[X_AXIS],destination[Y_AXIS],destination[Z_AXIS],destination[E_AXIS],feedrate*feedmultiply/60/100.0,active_extruder);}#endif//!(DELTA||SCARA)for(int8_ti=0;iNUM_AXIS;i++){current_position[i]=destination[i];//更新当前坐标的值为刚执行的目标坐标值}}好,看了一大段代码后小结一下。对于普通结构来说,G1每次将新读取gcode代码参数传递给prepare_move()函数中destination[i]数组以后,prepare_move()就会将其传递到plan_buffer_line()进行电机的运动。而delta结构呢,就相对复杂一点,G1命令读取了gcode代码参数后也是传递到prepare_move()函数中destination[i],然后marlin要计算目标坐标与当前坐标的笛卡尔距离,然后通过固定时间间隔的方式来将笛卡尔距离分成若干个小直线,通过这样的方式来就减少cpu的浮点预算量,然后再通过calculate_delta[i]函数来将简化后的destination[i]换算成三个电机的运动坐标,并传递到delta[i]中,接下来就是plan_buffer_line()了。最后!到了最后了!来看看calculate_delta()函数,这个函数的主要用途是将打印件的世界坐标转换为三个垂直的电机轴的运动坐标哦。注意:新的marlin支持SCARA结构的delta,那里也有个calculate_delta()的函数,不过那个跟rostock有点差异。所以我们还是看rostock的吧。voidcalculate_delta(floatcartesian[3]){delta[X_AXIS]=sqrt(delta_diagonal_rod_2-sq(delta_tower1_x-cartesian[X_AXIS])-sq(delta_tower1_y-cartesian[Y_AXIS]))+cartesian[Z_AXIS];delta[Y_AXIS]=sqrt(delta_diagonal_rod_2-sq(delta_tower2_x-cartesian[X_AXIS])-sq(delta_tower2_y-cartesian[Y_AXIS]))+cartesian[Z_AXIS];delta[Z_AXIS]=sqrt(delta_diagonal_rod_2-sq(delta_tower3_x-cart
本文标题:Delta(rostock型)3d打印机算法解读及调试步骤
链接地址:https://www.777doc.com/doc-2909796 .html