LinuxCNC学习(二)RS274NGC的源码分析

1、总体概述

首先通过rs274ngc_init()函数进行初始化,初始化内容包括读取rs274ngc.var和rs274ngc.tool_default文件,坐标,G模态组,M模态组以及其他G代码运行需要的状态量。然后就可以通过rs274ngc_read()函数进行读取G代码,然后进行语法和逻辑判断,最后通过rs274ngc_execute()函数进行G代码执行。

2、rs274ngc_read()函数的解读

首先判断当前G代码解释器是否正在执行探头测距,确保测距过程的完整(LinuxCNC内才有相应的配套逻辑),然后判断录入的当前行G代码内容是否非空,文件指针为空的情况,并通过CHK宏调用,实现错误代码的返回。
接下来执行read_text()函数,对传入的文本行逐字进行处理,处理后只保留小写和数字组成的紧凑G代码文本,其他空格,大写,tab键,注释等去掉。
接下来通过parse_line()函数进行逻辑检查,内部执行了四个函数:init_block()(初始化开始进入G代码分析时的状态,比如将R的状态量设置为-1,如果字符串中有R则将状态量修改为1等),read_items()(内部定义了一个函数指针数组,根据G代码的首字母,调用数组内的read_x函数,以sscanf函数进行转换),enhance_block()(对模态运动的逻辑检查和判定),check_items()(内部实现了3个函数check_g_codes判断G代码是否符合要求,check_m_codes判断M代码是否数量超过4个,check_other_codes判断其他类似于I被录入了,但确实G2,G3的模态等)。

3、rs274ngc_execute()函数的解读

首先处理以#xxx=xxx形式G代码对内部参数(1~5400)的设定,主要是MDI模式用于设定参数。
接下来主要执行了4个函数:execute_block(),write_g_codes(),write_m_codes(),write_settings()。

  • execute_block()函数
    这个函数实现了G代码的所有动作,包括
    打印注释,进给模式设置(G99 G98) 进给率 主轴转速 换刀,同时还对换刀M代码 主轴转向M代码 冷却M代码,还有一个feed override M48 M49处理
    同时还处理了G04暂停 G17,G18,G19等坐标平面 G20,G21单位制 G40,G41,G42左右刀补
    刀具偏置值 G44,G49 (G44 Hxx 长度补偿类似偏置值只有两位数表示)G54~G59.3坐标系
    G61 G64控制模式 G90,G91坐标类型 G98,G99进给模式 G10 坐标系设置 G28,G30回原点 G92坐标系偏移
    模态运动的处理 G0 G1 G2 G3 G80到G90间的循环代码处理等。
    以上所有操作都仅是输出字符串,没有关联的硬件操作过程。
  • write_g_codes()函数
    内部模态G码的保存和更新。
  • write_m_codes()函数
    内部模态M码的保存和更新。
  • write_settings()函数
    其他模态值的更新 行号 进给率 主轴速度等更新。

根据独立的G代码解释器并没有规定G代码的执行顺序,但是在LinuxCNC的execute_block()函数对G代码的执行顺序做了规定:

G-codes are are executed in the following order.
1.  mode 0, G4 only - dwell. Left here from earlier versions.
2.  mode 2, one of (G17, G18, G19) - plane selection.
3.  mode 6, one of (G20, G21) - length units.
4.  mode 15 one of (G07,G08) - lathe diameter mode
5.  mode 7, one of (G40, G41, G42) - cutter radius compensation.
6.  mode 8, one of (G43, G49) - tool length offset
7.  mode 12, one of (G54, G55, G56, G57, G58, G59, G59.1, G59.2, G59.3)
    - coordinate system selection.
8.  mode 13, one of (G61, G61.1, G64, G50, G51) - control mode
9.  mode 3, one of (G90, G91) - distance mode.
10.  mode 4, one of (G90.1, G91.1) - arc i,j,k mode.
11. mode 10, one of (G98, G99) - retract mode.
12. mode 0, one of (G10, G28, G30, G92, G92.1, G92.2, G92.3) -
13. mode 1, one of (G0, G1, G2, G3, G38.2, G80, G81 to G89, G33, G33.1, G76) - motion or cancel.
    G53 from mode 0 is also handled here, if present.
Some mode 0 and most mode 1 G-codes must be executed after the length units
are set, since they use coordinate values. Mode 1 codes also must wait
until most of the other modes are set.

4、G代码的处理

简单分析一下read_g()函数。为了简化G代码的处理,将G代码的数值进行放大10被,在rs274ngc.hh文件中有声明,比如G1用10表示。从中间数组的内容通过sscanf函数获取回一个dobule类型的数据,放大10倍后通过调用fix函数进行取整,以该整数为下标对所有支持G代码数组(1000个,-1表示不支持的G代码,其他有效值表示隶属的G代码组编号)进行取值,判定是否为-1,-1表示不支持的G代码操作,返回错误代码。同时判定当前的G代码是否是已经被同组的G代码赋值过了(init_block()函数会将初始状态设置为-1),出现同组的其他G代码赋值,返回错误代码。
根据rs274ngc.hh描述支持的G代码很少只有52个,为了丰富G代码翻译,LinuxCNC拓展到了92个,可以参考LinuxCNC的代码拓展需要的G代码到G代码解释器中。
尝试将G77固定循环车削指令(C类G代码)添加到G代码解释器中。动作分解是,①快速向下到定位点②横向进刀③竖向切削④快速回到开始点。

  1. 第一步
    在rs274ngc.hh中添加G77的宏
#define G_77		770
  1. 第二步
    在read_g()函数中找到_gees[1000]数组里面的第770个位置,将-1改为1号(设置为1号模组,关于模组分类可以看_gees[]数组源码位置的注释)。
  2. 第三步
    在check_g_codes()函数中作一些逻辑判断,比如要确保开始坐标点和目标坐标点不在一个点上。
int mode1 SET_TO block->g_modes[1];
if(mode1 IS G_77){
	CHK((block->x_flag IS ON) AND (block->z_flag IS ON), NCE_G77_error1);
	if(settings->distance_mode IS MODE_ABSOLUTE){
		CHK((fabs(block->x_number - settings->currentt_x) > 0.001) AND (fabs(block->z_number - settings->currentt_z) > 0.001), NCE_G77_error2);
	}else if(settings->distance_mode IS MODE_INCREMENTAL){
		CHK((fabs(block->x_number) > 0.001) AND (fabs(block->z_number) > 0.001), NCE_G77_error2);
	}
}
  1. 第四步
    将两个错误码的宏填到rs274ngc_return.hh文件中,同时将错误代码对应的文本填入到_rs274ngc_errors[]数组中,并且修改数组的长度值RS274NGC_MAX_ERROR到199
#define NCE_G77_error1		198
#define NCE_G77_error2		199

_rs274ngc_errors[]添加错误提示内容

    /* 198 */ "G77 XZ coordinates must be specified simultaneously", // G77 value
    /* 199 */ "G77 The target position and start point position cannot be the same", // G77 pos
  1. 第5步
    在G代码执行函数rs274ngc_execute()->execute_block()->convert_g()->convert_motion()添加一个分支。使G代码解释器执行G77程序。
else if(motion IS G_77){
	CHP(convert_cycle_g7x(motion, block, settings));
	settings->motion_mode SET_TO motion;
}
  1. 第6步
    实现convert_cycle_g7x()函数
static int convert_cycle_G7x(                  /* ARGUMENTS                                 */
int motion,                                   /* a g-code between G_71 and G_78, a canned cycle */
block_pointer block,                          /* pointer to a block of RS274 instructions       */
setup_pointer settings)                       /* pointer to machine settings                    */
{
    static char name[] SET_TO "convert_cycle_g7x";
    CANON_MOTION_MODE save_mode;
    int status;
    if(motion IS G_77){
    	// 路径1
         STRAIGHT_TRAVERSE(block->x_number, settings->current_y, settings->current_z
        #ifdef AA
                    ,             settings->current_a
        #else
        #ifdef ALL_AXES
                    , 0
        #endif
        #endif
        #ifdef BB
                    ,  settings->current_b
        #else
        #ifdef ALL_AXES
                    , 0
        #endif
        #endif
        #ifdef CC
                    ,  settings->current_c
        #else
        #ifdef ALL_AXES
                    , 0
        #endif
        #endif
                    );  
    // 路径2	
         STRAIGHT_FEED(block->x_number, settings->current_y, block->z_number
        #ifdef AA
                    ,             settings->current_a
        #else
        #ifdef ALL_AXES
                    , 0
        #endif
        #endif
        #ifdef BB
                    ,  settings->current_b
        #else
        #ifdef ALL_AXES
                    , 0
        #endif
        #endif
        #ifdef CC
                    ,  settings->current_c
        #else
        #ifdef ALL_AXES
                    , 0
        #endif
        #endif
                    );    
	// 路径3
         STRAIGHT_FEED(settings->current_x, settings->current_y, block->z_number
        #ifdef AA
                    ,             settings->current_a
        #else
        #ifdef ALL_AXES
                    , 0
        #endif
        #endif
        #ifdef BB
                    ,  settings->current_b
        #else
        #ifdef ALL_AXES
                    , 0
        #endif
        #endif
        #ifdef CC
                    ,  settings->current_c
        #else
        #ifdef ALL_AXES
                    , 0
        #endif
        #endif
                    );   
    // 路径4
         STRAIGHT_TRAVERSE(settings->current_x, settings->current_y, settings->current_z
        #ifdef AA
                    ,             settings->current_a
        #else
        #ifdef ALL_AXES
                    , 0
        #endif
        #endif
        #ifdef BB
                    ,  settings->current_b
        #else
        #ifdef ALL_AXES
                    , 0
        #endif
        #endif
        #ifdef CC
                    ,  settings->current_c
        #else
        #ifdef ALL_AXES
                    , 0
        #endif
        #endif
                    );                     	  
    }
    return RS274NGC_OK;
}
  1. 测试
    测试效果如图所示。
    G77测试代码

5、G代码解释器和运动控制库的连接

最终G代码执行的动作都是在canon.cc内进行实现,只需要将canon.cc内定义的基本函数,以队列的形式将数据传递到运动控制库通讯队列,发送数据到运动控制库,即可完成电机的动作。

  • 23
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值