2.7.2 motion.c
/*以绝对毫米坐标执行线性运动。进给率以毫米/秒为单位,除非invert_feed_rate为true。那么feed_rate意味着运动应该在(1分钟)/feed_rate时间内完成。注意:这是通往grbl规划器的主要通道。所有的直线运动,包括弧形线段,在传递给规划器之前必须通过这个例程。*/
void mc_line(float *target, plan_line_data_t *pl_data)
{
// 如果软限位触发.
if (bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE)) {
// 如果系统状态是不是JOG模式,检查目标点是否触发软限位
if (sys.state != STATE_JOG) { limits_soft_check(target); }
}
// 如果检查模式下,直接返回。
if (sys.state == STATE_CHECK_MODE) { return; }
do {
protocol_execute_realtime(); // 处理实时命令
if (sys.abort) { return; }
if ( plan_check_full_buffer() ) { protocol_auto_cycle_start(); } // 如果指令块缓存器
//(block_buffer)满,循环运行启动,等待指令块缓存器有空间
else { break; }//否则跳出
} while (1);
// 规划和排队指令进入规划缓冲区。
if (plan_buffer_line(target, pl_data) == PLAN_EMPTY_BLOCK) {//如果是一个空运动指令
if (bit_istrue(settings.flags,BITFLAG_LASER_MODE)) {//如果是激光模式
/* 需要缓冲区同步。 如果启用,立即通过PWM设置主轴运行状态,包括方向和主轴转速。同步后由spindle_sync()调用。*/
if (pl_data->condition & PL_COND_FLAG_SPINDLE_CW) {//主轴顺时针旋转
spindle_sync(PL_COND_FLAG_SPINDLE_CW, pl_data->spindle_speed);
}
}
}
}
/*position=起点xyz,target =终点xyz,offset =从起点xyz开始的偏移量,axis_X定义了工具空间中的圆平面,axis_linear是螺旋运动的方向,radius==圆半径,isclockwise为布尔值。用于矢量变换方向。弧线是通过生成大量微小的线性段来近似的。每个线段的弦向公差在settings.arc_tolerance中配置,它被定义为当端点都位于圆上时,线段到圆的最大法线距离。把圆弧分割成直线*/.
void mc_arc(float *target, plan_line_data_t *pl_data, float *position, float *offset, float radius,
uint8_t axis_0, uint8_t axis_1, uint8_t axis_linear, uint8_t is_clockwise_arc)
{
float center_axis0 = position[axis_0] + offset[axis_0]; //圆心点X
float center_axis1 = position[axis_1] + offset[axis_1]; //圆心点X
float r_axis0 = -offset[axis_0]; // 起点相对圆心位置X
float r_axis1 = -offset[axis_1]; // 起点相对圆心位置Y
float rt_axis0 = target[axis_0] - center_axis0; // 终点相对圆心位置X
float rt_axis1 = target[axis_1] - center_axis1; // 终点相对圆心位置Y
float angular_travel = atan2(r_axis0*rt_axis1-r_axis1*rt_axis0, r_axis0*rt_axis0+r_axis1*rt_axis1);//计算起点相对圆心的矢量和终点相对圆心的矢量得夹角
if (is_clockwise_arc) { //如是G02(顺时针运动),且大于负角度设置误差,置顺时针角度
if (angular_travel >= -ARC_ANGULAR_TRAVEL_EPSI