Delta3D打印机代码解读及调机心得(二) 

3D打印技术 /[固件]
2016-02-21 09:51
Delta (rostock型)3d打印机算法解读及调试步骤
Delta3D打印机代码.jpg

三、Marlin程序解读
这里鸭哥不打算讲marlin的整个loop()函数的流程,讲讲delta机型的核心部分。对于marlin来说,delta机型和非delta机型在对于温控、看门狗、电机运动甚至空间坐标等方面都是一样的。区别在哪里呢?区别就在与delta多了一个笛卡尔坐标转换的函数
Marlin的loop()主体流程
Void loop ()
{
Get_command() ;  //从sd卡或者串口获取gcode
Process_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()
{
Case 0: //g0->g1
Case 1 :
      {
     if(Stopped == false) {
        get_coordinates(); // 获取当前的坐标,这里是指打印件的世界坐标哦,不是delta的xyz电机的坐标哦!普通结构的打印机则是一样的。
          #ifdef FWRETRACT
            if(autoretract_enabled)
            if( !(code_seen('X') || code_seen('Y') || code_seen('Z')) && code_seen('E')) { //获取 命令中 xyze轴的参数
            Float echange=destination[E_AXIS]-current_position[E_AXIS]; //这里是算最小回抽值的,如果移动距离小于最小回抽值就不回抽了。这里是一个辅助功能。简单了解可以了。
              if((echange<-MIN_RETRACT && !retracted) || (echange>MIN_RETRACT && retracted)) { //move appears to be an attempt to retract or recover
                  current_position[E_AXIS] = destination[E_AXIS]; //hide the slicer-generated retract/recover from calculations
                  plan_set_e_position(current_position[E_AXIS]); //AND from the planner
                  retract(!retracted);
                  return;
              }
            }
          #endif //FWRETRACT
        prepare_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 、 destination 放到一个内存的一个缓存区里面,然后控制电机转多少圈这样一个作用的,具体代码可以自己去看,在一旦进入这个函数以后,delta和普通机型的代码都是一样的,也就是说delta和普通结构的电机控制其实是一样的。
Difference数组 :用来储存目标坐标和当前坐标之间的距离的,(这里是包含了xyze轴的数组)
Destination数组:目标坐标的数值,是从process_command()函数中G1读取XYZE参数获取的。
Current_position数组:当前坐标的数值,是从G1 命令中get_coordinates()传递过来的。如果是3个轴都归零的情况下,current_position就是储存三个坐标原点,如果开始运动了,这里的值就是上一个prepare_move()循环执行后上一次的destination的值。(这个下面会有看到赋值语句)
Delta数组:delta打印机的xyz三个电机要移动的距离
void prepare_move()
{

#ifdef DELTA // 设置机子是delta机型(rostock)
  float difference[NUM_AXIS]; //定义目标距离,用于转换坐标用的过渡变量
  for (int8_t i=0; i < NUM_AXIS; i++) {
    difference = destination - current_position;
  } //计算世界坐标的距离值
//***开始计算笛卡尔距离 并且暴力直线插值来减少运算量***//
  float cartesian_mm = sqrt(sq(difference[X_AXIS]) +
                            sq(difference[Y_AXIS]) +
                            sq(difference[Z_AXIS]));
  if (cartesian_mm < 0.000001) { cartesian_mm = abs(difference[E_AXIS]); }
  if (cartesian_mm < 0.000001) { return; }
  float seconds = 6000 * cartesian_mm / feedrate / feedmultiply;
  int steps = max(1, int(delta_segments_per_second * seconds));
  for (int s = 1; s <= steps; s++) {
    float fraction = float(s) / float(steps);//直线插值
    for(int8_t i=0; i < NUM_AXIS; i++) {
      destination = current_position + difference * 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 ! (defined DELTA || defined SCARA)
  // Do not use feedmultiply for E or Z only moves
  if( (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的值发送去运动缓存里面
  }
  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_t i=0; i < NUM_AXIS; i++) {
    current_position = destination; //更新当前坐标的值为刚执行的目标坐标值
  }
}

Delta3D打印机代码解读及调机心得(一)

Delta3D打印机代码解读及调机心得(三)

Delta3D打印机代码解读及调机心得(四)
声明:3D打印资源库(3dzyk)内网友所发表的所有内容及言论仅代表其本人,并不代表3D打印资源库(3dzyk)观点和立场;如对文章有异议或投诉,请联系kefu@3dzyk.cn。
一只,懒猫...

作者其他文章

Delta3D打印机代码解读及调机心得(二) 
快速回复 返回顶部 返回列表