基于Matlab的四象限圆弧插补程序
- 格式:doc
- 大小:33.50 KB
- 文档页数:4
基于MATLAB的优化双圆弧插补高次曲线的算法王霞琴;张伟华;王发生【摘要】针对普通数控机床加工的特点,推算了双圆弧插补法拟合高次曲线的数学模型,在拟合原曲线时,针对高次非圆曲线的特点,优化了双圆弧插补算法.并通过Matlab软件编程实现拟合过程,控制拟合误差.基于双圆弧插补法设计数控加工高次曲线的方法加工效果好,数控加工程序段和加工用时明显减少,且通用性和实用性强.【期刊名称】《机械研究与应用》【年(卷),期】2018(031)003【总页数】3页(P166-168)【关键词】高次曲线;双圆弧插补法;Matlab拟合【作者】王霞琴;张伟华;王发生【作者单位】兰州石化职业技术学院机械工程学院,甘肃兰州 730060;兰州石化职业技术学院机械工程学院,甘肃兰州 730060;甘肃驰奈生物能源系统有限公司,甘肃兰州 730050【正文语种】中文【中图分类】TH1640 引言工业技术的发展和消费理念的转变促进了曲线形产品的流行。
表面圆滑、线条流畅的物体形态除了有较好的使用性能,同时也赋予产品以时代感,在工业生产方面,曲线形模压产品更有便于脱模成形的特点。
因而,曲线元素被大量应用于产品当中。
然而,产品或模具外形轮廓加工时,所使用到的大多数普通数控加工设备只提供有直线和圆弧插补指令,对于非圆曲线轮廓的加工必须依靠直线段或者圆弧段去拟合逼近非圆曲线。
笔者主要针对非圆高次曲线轮廓外形,提出一种优化的双圆弧拟合方法,并运用MATLAB编程语言实现其拟合过程及误差分析,最终生成可加工的数控代码。
1 双圆弧插补的数学模型在进行产品加工时,刀具轨迹的规划是决定加工效果的重要因素之一。
对于非圆曲线的加工,如何生成的有效的加工代码,使之能最接近原曲线,并且任然保持光顺性是加工时要解决的难点问题。
针对非圆高次曲线光顺性在加工路径的设计时,考虑用双圆弧插补非圆高次曲线。
双圆弧插补原理:在给定非圆高次曲线上取有序点列在每相邻两点间作两个相切的圆弧,并使得所有圆弧在每个节点处都彼此相切,这样多段双圆弧的彼此相切就构成了与原曲线相似的一条光滑的曲线段,称为双圆弧插补。
焦作大学学报稼合版 , 年月开始一一一一一一一。
初始化。
、、、头“ 乐。
阮服‘ 名、二, “ 逆” 乐。
一一一一一二阮头, 户二二二侧「一一一一几二二二一一性 , 一一乐” 一一一一 , 「一一引, }卜日十一十一十加 , 丫十砂十】一 , 一 , 一一 , , 乙一一一一一二‘‘ 妞‘ 且一‘ 一皿‘ 一头一裔一生己坛舀石、之补 , 一护丫, 沿向走一步十阮沿向走一步 , , , 飞矛蔽丝・・士少二二二二 , 二二二已」头卜一仆一飞曰、一妞队 , 广 , 一阮一一, 比, 飞 , 、… 一一一一一一一阮种十阮一一知一一阮孰, 自竺万”二一生巴而‘ 一一一二二二二二二二一一一一一一一一一一一门豹。
, 石习 , 沿头 , 向走一步七一十” 二乐‘ 一一七二二二二二二一脚一一一一一童一一一一一一一一 , 巨二嘿狸飞蔽尸火’ 七、必当二二二二二一一一一结束图参考文献、四象限圆弧插补统一编程流程图、冯勇一种快速简捷的擂补执遥终王永章机床的数字控制技术哈点判别方法 , 组合机床与加工自动化对逐点比较括补法的改进尔滨工业大学出版社、黄义源机械设
备电气与数字撞制、李长有中央广播电视大学出版社组合机床与加工自动化。
直线插补与圆弧插补程序设计一.直线插补1.直线插补程序流程图直线插补程序流程图2.直线插补程序设计#include <stdio.h>#include <graphics.h>#include <stdlib.h>void cb_line(int x1, int y1, int x2, int y2) {int dx, dy, n, k, i, f;int x, y;dx = abs(x2-x1);dy = abs(y2-y1);n = dx + dy;if (x2 >= x1) {k = y2 >= y1 ? 1: 4;x = x1;y = y1;} else {k = y2 >= y1 ? 2: 3;x = x2;y = y2;}putpixel(x, y, 1);for (i = 0, f = 0; i < n; i++)if (f >= 0)switch (k) {case 1:putpixel(x++, y, 1);f -= dy;break;case 2:putpixel(x, y++, 1);f -= dx;break;case 3:putpixel(x--, y, 1);f -= dy;break;case 4:putpixel(x, y--, 1);f -= dx;break;}elseswitch (k) {case 1:putpixel(x, y++, 1);f += dx;break;case 2:putpixel(x--, y, 1);f += dy;break;case 3:putpixel(x, y--, 1);f += dx;break;case 4:putpixel(x++, y, 1);f += dy;break;}}int main(){cb_line(0,0,15,20); /* <--- you forgot ; here */return 0;}二.圆弧插补2.1.四象限圆弧插补程序流程图2.1四象限圆弧插补程序设计#include <stdio.h>#include <math.h>int ArcXY(double dfx0,double dfy0,double dfrx, double dfry,int angle); int symbol(double number);main(){ArcXY(0,0,-3,5,360);getch();}int ArcXY(double dfx0,double dfy0,double dfrx, double dfry,int angle) {FILE *f1;double i,j,dx,dy,dfr,x,y,ang,step,f = 0.01;int flag,tempx,tempy,statex,statey,direction = 1;dfr = sqrt((dfrx - dfx0) * (dfrx - dfx0) + (dfry - dfy0) * (dfry - dfy0));if(dfx0 == 0){dfx0 = 1;dfrx = dfrx + 1;statex =1;}if(dfy0 == 0){dfy0 = 1;dfry = dfry + 1;statey =1;}dfrx = 2 * dfx0 - dfrx;i = dfx0 - dfrx;j = dfy0 - dfry;x = dfx0 ;y = dfy0 ;step = ang = 180 * 2 * asin(f/(2*dfr))/3.1415926;if(((dfx0 > 0) && (dfy0 > 0)) || ((dfx0 < 0) && (dfy0 < 0))){flag = direction;}if(((dfx0 < 0) && (dfy0 > 0)) || ((dfx0 > 0) && (dfy0 < 0))) {flag = -direction;}f1=fopen("c:\\c.txt","w+");if(statex ==1){x = x - 1;}if(statey ==1){y = y - 1;}fprintf(f1,"%f,",x);fprintf(f1,"%f\n",y);while(ang < angle){dx = f * (j + flag*(f * i)/(2 * dfr))/dfr;dy = f * (i - flag*(f * j)/(2 * dfr))/dfr;tempx = symbol(x);tempy = symbol(y);x = x + dx;y = y + dy;fprintf(f1,"%f,",x);fprintf(f1,"%f\n",y);if( (tempx !=symbol(x)) || (tempy != symbol(y)) ){flag = -flag;}i = i - dx;j = j + dy;ang = ang + step;}return 0;}int symbol(double number) {if(number > 0){return 1;}else{return -1;}}。
数控技术课程设计说明书设计题目:数字积分法圆弧插补计软件设计指导老师:专业:机械设计制造及其自动化班级:机姓名:学号:目录一、课程设计题目 (1)二、课程设计的目的 (1)三、课程设计使用的主要仪器设备 (1)四、课程设计的任务题目描述和要求 (1)五、数字积分法插补原理 (2)5.1从几何角度来看积分运算 (2)5.2数字积分圆弧插补 (3)5.3数字积分法圆弧插补程序流程图 (5)5.4插补实例 (6)六、程序清单 (7)七、软件运行效果仿真 (18)八、课程小节 (21)九、参考文献 (22)一、课程设计题目数字积分法第一、二、三、四象限顺、逆圆插补计算二、课程设计的目的《数控原理与系统》是自动化(数控)专业的一门主要专业课程,安排课程设计的目的是通过课程设计方式使学生进一步掌握和消化数控原理基本内容,了解数控系统的组成,掌握系统控制原理和方法,通过设计与调试,掌握各种功能实的现方法,为今后从事数控领域的工作打下扎实的基础。
1)了解连续轨迹控制数控系统的组成原理。
2) 掌握数字积分法(DDA)插补的基本原理。
3)掌握数字积分法(DDA)插补的软件实现方法。
三、课程设计使用的主要仪器设备1、PC计算机一台2、数控机床实验装置一台3、支持软件若干(选用VB环境)四、课程设计的任务题目描述和要求数字积分法又称数字微分分析法DDA(Digital Differential Analyzer)。
数字积分法具有运算速度快、脉冲分配均匀、易于实现多坐标联动及描绘平面各种函数曲线的特点,应用比较广泛。
其缺点是速度调节不便,插补精度需要采取一定措施才能满足要求。
由于计算机有较强的计算功能和灵活性,采用软件插补时,上述缺点易于克服。
本次课程设计具体要求如下:(1)掌握数字积分插补法基本原理(2)设计出数字积分(DDA)插补法插补软件流程图(3)编写出算法程序清单算法描述(数字积分法算法在VB中的具体实现)(4)要求软件能够实现第一、二、三、四象限顺、逆圆插补计算(5)软件运行仿真效果插补结果要求能够以图形模式进行输出五、数字积分法插补原理数字积分法又称数字积分分析法DDA(Digital differential Analyzer),简称积分器,是在数字积分器的基础上建立起来的一种插补算法。
四象限直线插补计算程序
四象限直线插补计算程序是一种用于机器人运动控制的算法,通过计算机编程实现。
在机器人控制系统中,直线插补是指将机器人的起始位置和目标位置之间的直线路径划分成一系列离散的插补点,并根据路径上的每个插补点的位置、速度和加速度进行控制,使得机器人能够顺利达到目标位置。
四象限直线插补计算程序的核心思想是将直线路径上的插补点分为
四个象限,每个象限都有不同的速度和加速度控制策略。
具体而言,四象限分别为正加速度、匀速、负加速度和停止。
首先,程序会根据起始位置和目标位置计算出路径的总长度,并根据设定的速度和加速度限制计算出每个象限的长度。
然后,程序会根据象限长度和限制条件计算出每个象限的插补点个数。
接下来,程序会根据插补点个数和限制条件,计算出每个插补点的位置、速度和加速度。
在正加速度象限,插补点的位置和速度会逐渐增加,加速度保持一个固定的正值。
在匀速象限,插补点的位置和速度保持稳定,加速度为零。
在负加速度象限,插补点的位置和速度会逐渐减小,加速度保持一个固定的负值。
在停止象限,插补点的位置和
速度为目标位置和速度,加速度为零。
最后,程序会根据计算出的插补点的位置、速度和加速度,控制机器人按照插补点的顺序依次运动,直到达到目标位置。
这样,通过四象限直线插补计算程序,机器人可以按照设定的速度和加速度限制,平滑地完成直线路径的运动控制,提高运动的精度和稳定性。
除了四象限直线插补计算程序,还有其他的插补算法,如三次样条插补算法和五次多项式插补算法等。
这些算法都有各自的特点和适用范围,在实际应用中可以根据具体的需求选择合适的插补算法。
matlab四象限直线插补计算
在MATLAB中进行四象限直线插补计算的步骤如下:
1. 定义起始点和终止点的坐标。
例如,起始点为(0,0),终止点为(10,5)。
2. 计算两点之间的距离和斜率。
使用勾股定理计算两点之间的距离,并使用斜率公式计算两点之间的斜率。
假设起始点为(x1,y1),终止点为(x2,y2),则距离和斜率的计算方式如下:
距离:distance = sqrt((x2-x1)^2 + (y2-y1)^2)
斜率:slope = (y2-y1)/(x2-x1)
3. 确定每个插补步长的大小。
插补步长的大小应该与所需精度和速度相匹配。
通常情况下,步长应该小于或等于机床的控制分辨率。
4. 进行四象限直线插补计算。
根据所选步长以及距离和斜率计算出每个插补点的坐标。
具体计算方式如下:
- 当斜率大于等于0且小于等于1时,x坐标递增,y坐标按比例递增。
- 当斜率大于1时,y坐标递增,x坐标按比例递增。
- 当斜率小于0且大于等于-1时,x坐标递增,y坐标按比例递减。
- 当斜率小于-1时,y坐标递减,x坐标按比例递减。
5. 将插补点的坐标传输给机床进行控制。
将四象限直线插补计算出的每个插补点的坐标值传输给机床进行控制,从而实现直线插补运动。
2010级硕士研究生《数控理论与加工技术》作业专业:机械设计及理论教师:罗红波一、编程实现四个象限圆弧顺时针逐点比较法插补计数,逐条程序注释说明。
解:以下为基于单片机汇编语言的4个象限顺圆弧逐点比较法插补程序,具备过象限插补的能力(实际上就是实现了数控编程G代码中的顺时针圆弧插补指令G02的功能)。
其中用R表示圆弧,S表示顺时针,SR1、SR2、SR3、SR4分别表示第一象限、第二象限、第三象限、第四象限的顺圆弧。
主程序根据偏差F:0F分为两大板块:<≥F及0⑴当偏差0F时,首先根据圆弧标志判断圆弧所在象限(起始为SR1、SR2、≥SR3或SR4),然后分程序段分别实现SR1、SR2、SR3、SR4或者SR1→SR4、SR2→SR1、SR3→SR2、SR4→SR3(过象限插补能力设计)的逐点比较法插补计数。
之后,通过程序循环,可实现顺时针整圆弧的插补计数。
(程序段RP_2_0之前板块)⑵当偏差0F时,首先根据圆弧标志判断圆弧所在象限(起始为SR1、SR2、<SR3或SR4),然后分程序段分别实现SR1、SR2、SR3、SR4或者SR1→SR4、SR2→SR1、SR3→SR2、SR4→SR3(过象限插补能力设计)的逐点比较法插补计数。
之后,通过程序循环,可实现顺时针整圆弧的插补计数。
(程序段RP_2_0之后板块);****************************************************************************** ;顺圆弧插补程序: RP;****************************************************************************** RP: MOV A, #00HMOV Fz1, A ;偏差单元初始化清零MOV Fz2, AMOV Fz3, ARP0: MOV DPTR, #FEED%MOVX A, @DPTRCJNE A, #01H, RP0_1MOV R6, #02HSJMP RP0_5RP0_1: CJNE A, #02H, RP0_2MOV R6, #04HSJMP RP0_5RP0_2: CJNE A, #03H, RP0_3MOV R6, #08HSJMP RP0_5RP0_3: MOV R6, #10HRP0_5: LCALL DEL1MS ;调用延时1MS子程序MOV A, Fz1JB ACC.7, RP_2 ;F<0,则转MOV A, FLAGANL A, #07H ;圆弧标志:000=SR1,001=SR2CJNE A, #00H, RP_1_1MOV A, #03H ;说明是SR1,应走-ZMOV F_ORIENT, ALCALL DISP_XZLCALL MAN_MOVE ;按标志走步LCALL DISP_XZLCALL COPM_F1 ;计算偏差及动点坐标:F<-F-2Z+1,Zi<-Zi-1MOV A, FLAGANL A, #00100000B ;判是否过象限JZ RP_1_0_2 ;不过象限则转MOV A, Zi1 ;判是否要过象限了ORL A, Zi2ORL A, Zi3JNZ RP_1_0_3 ;<>0,还不过象限MOV A, FLAG ;否则,过了象限为SR4SETB ACC.0 ;#03H=SR4SETB ACC.1CLR ACC.2CLR ACC.5 ;清过象限标志位////98/7/10MOV FLAG, ASETB F0 ;////98/7/10LCALL NEW_STEPS ;重新计算步数MOV A, #00H ;偏差单元清零MOV Fz1, AMOV Fz2, AMOV Fz3, ALJMP RP0RP_1_0_3: LCALL RP_IS_END ;判是否到终点:Xe=Xi,Ze=ZiJNC RP_1_0_4 ;C=1,到了;否则,未到RET ;到了,就返回RP_1_0_4: LJMP RP0 ;继续插补RP_1_0_2: LCALL RP_IS_OVER ;步数减1,并判是否结束JNC RP_1_0_5RETRP_1_0_5: LJMP RP0RP_2: LJMP RP_2_0 ;F<0处理RP_1_1: CJNE A, #01H, RP_1_2MOV A, #02H ;说明是SR2,应走+XMOV F_ORIENT, ALCALL DISP_XZLCALL MAN_MOVE ;按标志走步LCALL DISP_XZLCALL COPM_F3 ;计算偏差及动点坐标:F<-F-2X+1,Xi<-Xi-1MOV A, FLAGANL A, #00100000B ;判是否过象限JZ RP_1_1_2 ;不过象限则转MOV A, Xi1 ;否则,判是否要过象限了ORL A, Xi2ORL A, Xi3JNZ RP_1_1_3 ;<>0,还不过象限MOV A, FLAG ;否则,过了象限为SR1CLR ACC.0 ;#00H=SR1CLR ACC.1CLR ACC.2CLR ACC.5MOV FLAG, ACLR F0LCALL NEW_STEPSMOV A, #00HMOV Fz1, AMOV Fz2, AMOV Fz3, ALJMP RP0RP_1_1_3: LCALL RP_IS_END ;判是否到终点:Xe=Xi,Ze=ZiJNC RP_1_1_4 ;C=1,到了;否则,未到RET ;到了,就返回RP_1_1_4: LJMP RP0 ;继续插补RP_1_1_2: LCALL RP_IS_OVER ;步数减1,并判是否结束JNC RP_1_1_5RETRP_1_1_5: LJMP RP0RP_1_2: CJNE A, #02H, RP_1_3MOV A, #04H ;说明是SR3,应走+ZMOV F_ORIENT, ALCALL DISP_XZLCALL MAN_MOVE ;按标志走步LCALL DISP_XZLCALL COPM_F1 ;计算偏差及动点坐标:F<-F-2Z+1,Zi<-Zi-1MOV A, FLAGANL A, #00100000B ;判是否过象限JZ RP_1_2_2 ;不过象限则转MOV A, Zi1 ;否则,判是否要过象限了ORL A, Zi2ORL A, Zi3JNZ RP_1_2_3 ;<>0,还不过象限MOV A, FLAG ;否则,过了象限为SR2SETB ACC.0 ;#01H=SR2CLR ACC.1CLR ACC.2CLR ACC.5MOV FLAG, ASETB F0LCALL NEW_STEPSMOV A, #00HMOV Fz1, AMOV Fz2, AMOV Fz3, ALJMP RP0RP_1_2_3: LCALL RP_IS_END ;判是否到终点:Xe=Xi,Ze=ZiJNC RP_1_2_4 ;C=1,到了;否则,未到RET ;到了,就返回RP_1_2_4: LJMP RP0 ;继续插补RP_1_2_2: LCALL RP_IS_OVER ;步数减1,并判是否结束JNC RP_1_2_5RETRP_1_2_5: LJMP RP0RP_1_3: CJNE A, #03H, RP_1_4MOV A, #01H ;说明是SR4,应走-XMOV F_ORIENT, ALCALL DISP_XZLCALL MAN_MOVE ;按标志走步LCALL DISP_XZLCALL COPM_F3 ;计算偏差及动点坐标:F<-F-2X+1,Xi<-Xi-1MOV A, FLAGANL A, #00100000B ;判是否过象限JZ RP_1_3_2 ;不过象限则转MOV A, Xi1 ;否则,判是否要过象限了ORL A, Xi2ORL A, Xi3JNZ RP_1_3_3 ;<>0,还不过象限MOV A, FLAG ;否则,过了象限为SR3CLR ACC.0 ;#02H=SR3SETB ACC.1CLR ACC.2CLR ACC.5MOV FLAG, ACLR F0LCALL NEW_STEPSMOV A, #00HMOV Fz1, AMOV Fz2, AMOV Fz3, ALJMP RP0RP_1_3_3: LCALL RP_IS_END ;判是否到终点:Xe=Xi,Ze=ZiJNC RP_1_3_4 ;C=1,到了;否则,未到RET ;到了,就返回RP_1_3_4: LJMP RP0 ;继续插补RP_1_3_2: LCALL RP_IS_OVER ;步数减1,并判是否结束JNC RP_1_3_5RETRP_1_3_5: LJMP RP0;F<0处理RP_2_0: MOV A, FLAGANL A, #07H;圆弧标志:000=SR1,001=SR2CJNE A, #00H, RP_2_1MOV A, #02H ;说明是SR1,应走+XMOV F_ORIENT, ALCALL DISP_XZLCALL MAN_MOVE ;按标志走步LCALL DISP_XZLCALL COPM_F2 ;计算偏差及动点坐标:F<-F+2X+1,Xi<-Xi+1MOV A, FLAGANL A, #00100000B ;判是否过象限JZ RP_2_0_2 ;不过象限,则转MOV A, Zi1 ;判是否要过象限了ORL A, Zi2ORL A, Zi3JNZ RP_2_0_3 ;<>0,还不过象限MOV A, FLAG ;否则,过了象限为SR4SETB ACC.0 ;#03H=SR4SETB ACC.1CLR ACC.2CLR ACC.5MOV FLAG, ASETB F0LCALL NEW_STEPSMOV A, #00HMOV Fz1, AMOV Fz2, AMOV Fz3, ALJMP RP0RP_2_0_3: LCALL RP_IS_END ;判是否到终点:Xe=Xi,Ze=ZiJNC RP_2_0_4 ;C=1,到了;否则,未到RET ;到了,就返回RP_2_0_4: LJMP RP0 ;继续插补RP_2_0_2: LCALL RP_IS_OVER ;步数减1,并判是否结束JNC RP_2_0_5RETRP_2_0_5: LJMP RP0RP_2_1: CJNE A, #01H, RP_2_2MOV A, #04H ;说明是SR2,应走+ZMOV F_ORIENT, ALCALL DISP_XZLCALL MAN_MOVE ;按标志走步LCALL DISP_XZLCALL COPM_F4 ;计算偏差及动点坐标:F<-F+2Z+1,Zi<-Zi+1MOV A, FLAGANL A, #00100000B ;判是否过象限JZ RP_2_1_2 ;不过象限则转MOV A, Xi1 ;否则,判是否要过象限了ORL A, Xi2ORL A, Xi3JNZ RP_2_1_3 ;<>0,还不过象限MOV A, FLAG ;否则,过了象限为SR1CLR ACC.0 ;#00H=SR1CLR ACC.1CLR ACC.2CLR ACC.5MOV FLAG, ACLR F0LCALL NEW_STEPSMOV A, #00HMOV Fz1, AMOV Fz2, AMOV Fz3, ALJMP RP0RP_2_1_3: LCALL RP_IS_END ;判是否到终点:Xe=Xi,Ze=ZiJNC RP_2_1_4 ;C=1,到了;否则,未到RET ;到了,就返回RP_2_1_4: LJMP RP0 ;继续插补RP_2_1_2: LCALL RP_IS_OVER ;步数减1,并判是否结束JNC RP_2_1_5RETRP_2_1_5: LJMP RP0RP_2_2: CJNE A, #02H, RP_2_3MOV A, #01H ;说明是SR3,应走-XMOV F_ORIENT, ALCALL DISP_XZLCALL MAN_MOVE ;按标志走步LCALL DISP_XZLCALL COPM_F2 ;计算偏差及动点坐标:F<-F+2X+1,Xi<-Xi+1MOV A, FLAGANL A, #00100000B ;判是否过象限JZ RP_2_2_2 ;不过象限则转MOV A, Zi1 ;否则,判是否要过象限了ORL A, Zi2ORL A, Zi3JNZ RP_2_2_3 ;<>0,还不过象限MOV A, FLAG ;否则,过了象限为SR2SETB ACC.0 ;#01H=SR2CLR ACC.1CLR ACC.2CLR ACC.5MOV FLAG, ASETB F0LCALL NEW_STEPSMOV A, #00HMOV Fz1, AMOV Fz2, AMOV Fz3, ALJMP RP0RP_2_2_3: LCALL RP_IS_END ;判是否到终点:Xe=Xi,Ze=ZiJNC RP_2_2_4 ;C=1,到了;否则,未到RET ;到了,就返回RP_2_2_4: LJMP RP0 ;继续插补RP_2_2_2: LCALL RP_IS_OVER ;步数减1,并判是否结束JNC RP_2_2_5RETRP_2_2_5: LJMP RP0RP_2_3: CJNE A, #03H, RP_2_4MOV A, #03H ;说明是SR4,应走-ZMOV F_ORIENT, ALCALL DISP_XZLCALL MAN_MOVE ;按标志走步LCALL DISP_XZLCALL COPM_F4 ;计算偏差及动点坐标:F<-F+2Z+1,Zi<-Zi+1MOV A, FLAGANL A, #00100000B ;判是否过象限JZ RP_2_3_2 ;不过象限则转MOV A, Xi1 ;否则,判是否要过象限了ORL A, Xi2ORL A, Xi3JNZ RP_2_3_3 ;<>0,还不过象限MOV A, FLAG ;否则,过了象限为SR3CLR ACC.0 ;#02H=SR3SETB ACC.1CLR ACC.2CLR ACC.5MOV FLAG, ACLR F0LCALL NEW_STEPSMOV A, #00HMOV Fz1, AMOV Fz2, AMOV Fz3, ALJMP RP0RP_2_3_3: LCALL RP_IS_END ;判是否到终点:Xe=Xi,Ze=ZiJNC RP_2_3_4 ;C=1,到了;否则,未到RET ;到了,就返回RP_2_3_4: LJMP RP0 ;继续插补RP_2_3_2: LCALL RP_IS_OVER ;步数减1,并判是否结束JNC RP_2_3_5RETRP_2_3_5: LJMP RP0二、论述数控机床的发展趋势。
Private Sub Command1_Click()Picture1.ForeColor = vbBlackPicture1.DrawWidth = 2Picture1.Line (500, 500)-(500, 5500) '坐标系Picture1.Line (500, 500)-(5500, 500)Picture1.Line (500, 5500)-(460, 5400) '箭头Picture1.Line (500, 5500)-(540, 5400)Picture1.Line (5500, 500)-(5400, 460)Picture1.Line (5500, 500)-(5400, 540)Picture1.Line (5850, 550)-(5750, 450)Picture1.Line (5850, 450)-(5750, 550)Picture1.Line (500, 5800)-(450, 5750)Picture1.Line (500, 5800)-(550, 5750)Picture1.Line (500, 5800)-(500, 5900)Picture1.Line (430, 5800)-(380, 5800)Picture1.ForeColor = vbRedPicture1.DrawWidth = 4Picture1.Line (500, 500)-(500 + 400 * Int(Text3), 500 - 400 * Int(Text4))Command2.Enabled = True100Text1.SetFocusEnd SubPrivate Sub Command2_Click()Form1.ClsDim k, m, j, l, n, F(20) As Integerm = 0l = 0k = 0F(m) = 0Picture1.ForeColor = vbGreenPicture1.DrawWidth = 3j = Abs(Int(Text3)) + Abs(Int(Text4)) '总步数Form1.CurrentX = 200Form1.CurrentY = 200Print "初始:进给方向" & "F(m)=0" & " Xe=" & Int(Text3) & " Ye=" & Int(Text4) & " ∑= " & jFor n = 1 To jIf F(m) >= 0 And j > 0 Then 'X方向进给m = m + 1 '序号l = l + 1 'X方向进给l加1F(m) = F(m - 1) - Abs(Int(Text4))Picture1.Line (500 + 400 * (l - 1), 500 + k * 400)-(500 + 400 * (l), 500 + k * 400)Form1.CurrentX = 200Form1.CurrentY = 200 + m * 300Print "第" & m & "步" & " △x F(" & m & ")= " & F(m) & " " & "x=" & l & " " & "y=-"; k & " ∑=" & j - nElse 'Y方向进给k = k + 1m = m + 1Picture1.Line (500 + 400 * l, 500 + (k - 1) * 400)-(500 + 400 * l, 500 + k * 400)F(m) = F(m - 1) + Abs(Int(Text3))Form1.CurrentX = 200Form1.CurrentY = 200 + m * 300Print "第" & m & "步" & " △y F(" & m & ")= " & F(m) & " " & "x="; l & " " & "y=-"; k & " ∑=" & j - nEnd IfNext nEnd SubPrivate Sub Command3_Click()Text3.Text = ""Text4.Text = ""Picture1.ClsForm1.ClsEnd SubPrivate Sub Command4_Click()EndEnd Sub。
17-6-16上午10:16H:\Matlab Do...\demo.m第 1 页,共 1 页%% 初始化clear,clcclose allwarning offfeature jit off%% 主程序% R代表所插补的圆的半径R=10;%ThetaAround代表所要插补的角度范围ThetaAround=[135,90;90,0;0,-45];;% Use_SN代表所在控制的插补方向% Use_S表示进行顺向插补 Use_N表示进行逆向插补Use_SN='Use_S';% 通过OCT_MControl函数进行插补并返回插补信息% Data是切削刀头的移动坐标数据% MovePosition是切削刀头的移动方向信息[Data,MovePosition]=OCT_MControl(ThetaAround,R,Use_SN);%% 作图,动态演示插补过程hold ongrid onaxis equalezplot(strcat('x^2+y^2=',num2str(R^2)),[-R,R]);mycomet(Data.X,Data.Y)function [Data,MovePosition]=OCT_MControl(ThetaAround,O_R,Use_SN) % 插补过程的总控制函数% 对于跨过几个象限的圆弧,程序可以分段对其每个象限圆弧进行插补Data.X=[];Data.Y=[];Data.Fm=[];% 确定插补段数for n=1:size(ThetaAround,1)% 将半径及角度信息转换为插补的起始与终止点坐标Position.X_FirstPosition=O_R*cosd(ThetaAround(n,1));Position.Y_FirstPosition=O_R*sind(ThetaAround(n,1));Position.X_EndPosition=O_R*cosd(ThetaAround(n,2));Position.Y_EndPosition=O_R*sind(ThetaAround(n,2));% 对每一象限的圆弧进行单独插补并返回数据TmpData{n,1}=OCT_GetData(OCT_Function(Position,Use_SN));% 记录移动方向信息MovePosition{n,1}=TmpData{n,1}.MovePosition;% 记录坐标及误差等数据信息Data.X=[Data.X;TmpData{n,1}.X];Data.Y=[Data.Y;TmpData{n,1}.Y];Data.Fm=[Data.X;TmpData{n,1}.Fm];endfunction mycomet(varargin)[ax,args,nargs] = axescheck(varargin{:});if nargs < 1error(message('MATLAB:narginchk:notEnoughInputs'));elseif nargs > 3error(message('MATLAB:narginchk:tooManyInputs'));endif nargs < 2, x = args{1}; y = x; x = 1:length(y); endif nargs == 2, [x,y] = deal(args{:}); endif nargs < 3, p = 0.10; endif nargs == 3, [x,y,p] = deal(args{:}); endif ~isscalar(p) || ~isreal(p) || p < 0 || p >= 1error(message('MATLAB:comet:InvalidP'));endax = newplot(ax);if ~ishold(ax)[minx,maxx] = minmax(x);[miny,maxy] = minmax(y);axis(ax,[minx maxx miny maxy])endco = get(ax,'colororder');m = length(x);k = round(p*m);if size(co,1)>=3colors = [ co(1,:);co(2,:);co(3,:)];lstyle = '-';elsecolors = repmat(co(1,:),3,1);lstyle = '--';endhead = line('parent',ax,'color',colors(1,:),'marker','o','linestyle','none', ...'xdata',x(1),'ydata',y(1),'Tag','head');body = matlab.graphics.animation.AnimatedLine('color',colors(2,:),...'linestyle',lstyle,...'Parent',ax,...'MaximumNumPoints',max(1,k),'tag','body');tail = matlab.graphics.animation.AnimatedLine('color',colors(3,:),...'linestyle','-',...'Parent',ax,...'MaximumNumPoints',1+m,'tag','tail');if ( length(x) < 2000 )updateFcn = @()drawnow;elseupdateFcn = @()drawnow('update');endfor i = 1:kpause(0.1);set(head,'xdata',x(i),'ydata',y(i));if ~( body.isvalid() )returnendaddpoints(body,x(i),y(i));updateFcn();enddrawnow;for i = k+1:mpause(0.1);set(head,'xdata',x(i),'ydata',y(i));if ~( body.isvalid() )returnendaddpoints(body,x(i),y(i));addpoints(tail,x(i-k),y(i-k));updateFcn();enddrawnow;for i = m+1:m+kpause(0.1);if ~( body.isvalid() )returnendaddpoints(tail,x(i-k),y(i-k));updateFcn();enddrawnow;endfunction [minx,maxx] = minmax(x) minx = min(x(isfinite(x)));maxx = max(x(isfinite(x)));if minx == maxxminx = maxx-1;maxx = maxx+1;endendfunction CurrentData=OCT_GetData(OriginData) % 提取插补返回信息% 因为插补返回的数据信息是进行的打包的% 所以还需要从打包的数据中把数据提取出来Tmp1=zeros(length(OriginData),4);Tmp2=[];for n=1:length(OriginData)Tmp1(n,1:3)=OriginData{n,1}.Data;Tmp2{n,1}=OriginData{n,1}.MovePosition; end% 重新构建数据CurrentData.X=Tmp1(:,1);CurrentData.Y=Tmp1(:,2);CurrentData.Fm=Tmp1(:,3);CurrentData.MovePosition=Tmp2;endfunction Message=OCT_Function(Position,Use_SN)% 对单个区间的圆弧进行插补并返回进程信息TmpData.Xm=abs(Position.X_FirstPosition);TmpData.Ym=abs(Position.Y_FirstPosition);TmpData.Fm=0;Message{1,1}.MovePosition='FirstPosition';Message{1,1}.Data=[Position.X_FirstPosition,Position.Y_FirstPosition,0]; StepNumber=abs(Position.X_FirstPosition-Position.X_EndPosition)+...abs(Position.Y_FirstPosition-Position.Y_EndPosition);switch Use_SNcase'Use_S'% 使用顺向插补的处理程序段for n=1:StepNumber% 判别所要插补的象限if Position.X_FirstPosition>=0 && Position.Y_FirstPosition>0 % SR1[TmpData,List]=OCT_SetData(OCT_ForS(TmpData,1),1);Message{n+1,1}=List;elseif Position.X_FirstPosition>0 && Position.Y_FirstPosition<=0 % SR4[TmpData,List]=OCT_SetData(OCT_ForS(TmpData,4),4);Message{n+1,1}=List;elseif Position.X_FirstPosition<0 && Position.Y_FirstPosition>=0 % SR2[TmpData,List]=OCT_SetData(OCT_ForS(TmpData,2),2);Message{n+1,1}=List;elseif Position.X_FirstPosition<=0 && Position.Y_FirstPosition<0 % SR3[TmpData,List]=OCT_SetData(OCT_ForS(TmpData,3),3);Message{n+1,1}=List;endendcase'Use_N'% 使用逆向插补的处理程序段for n=1:StepNumber% 判别所要插补的象限if Position.X_FirstPosition>0 && Position.Y_FirstPosition>=0 % NR1[TmpData,List]=OCT_SetData(OCT_ForN(TmpData,1),1);Message{n+1,1}=List;elseif Position.X_FirstPosition>=0 && Position.Y_FirstPosition<0 % NR4[TmpData,List]=OCT_SetData(OCT_ForN(TmpData,4),4);Message{n+1,1}=List;elseif Position.X_FirstPosition<=0 && Position.Y_FirstPosition>0 % NR2[TmpData,List]=OCT_SetData(OCT_ForN(TmpData,2),2);Message{n+1,1}=List;elseif Position.X_FirstPosition<0 && Position.Y_FirstPosition<=0 % NR3[TmpData,List]=OCT_SetData(OCT_ForN(TmpData,3),3);Message{n+1,1}=List;endendendendfunction [TheNowPosition,RuternMessage]=OCT_SetData(TheLastPosition,Quadrant)% 将切削信息打包返回,切削刀头坐标位置进行更新% 将上次插补的结束点坐标变为下次插补的开始点坐标TheNowPosition.Xm=TheLastPosition.NewXm;TheNowPosition.Ym=TheLastPosition.NewYm;TheNowPosition.Fm=TheLastPosition.NewFm;% 装载刀头的移动方向信息RuternMessage.MovePosition=TheLastPosition.MovePosition;% 因为插补数据中的Xm、YM信息是取了绝对值的。
X0=input('请输入起点横轴坐标x: ');
Y0=input('请输入起点纵轴坐标y: ');
NXY=input('请输入差补步数: ');
pace=input('请输入差补步长: ');
RNSS=input('请选择差补走向(1代表顺时针/2代表逆时针): ');
XM=X0;
YM=Y0;
%画基准圆
R=sqrt(X0*X0+Y0*Y0);
alpha=0:pi/20:2*pi;
xx=R*cos(alpha);
yy=R*sin(alpha);
plot(xx,yy,'g:');
hold on;
axis equal;
%针对跨象限运行时对ZF初始化(由于在跨象限运行时不改变ZF值所以必须对其初始化)
ZF=(RNSS==1)*(((Y0==0)*((X0>0)*4+(X0<0)*3))+((X0==0)*((Y0>0)*1+(Y0<0) *2)))+...
(RNSS~=1)*(((Y0==0)*((X0>0)*3+(X0<0)*4))+((X0==0)*((Y0>0)*2+(Y0<0)*1) ));
%建立NXY次循环来实现差补计算与绘图
for num=1:NXY
%FM值判断
FM=XM*XM+YM*YM-X0*X0-Y0*Y0;
%象限判断(RNS为1,2,3,4分别代表1,2,3,4象限)
RNS=(XM>0)*((YM>0)*1+(YM<0)*4)+(XM<0)*((YM>0)*2+(YM<0)*3);
%走步计算(RNS百位为1表示逆时针画圆,十位为1表示FM<0,个位数字表示所在
象限,ZF代表走步方向)
switch RNS+((FM<0)*10)+(RNSS~=1)*100 case 001
ZF=4;
case 002
ZF=1;
case 003
ZF=3;
case 004
ZF=2;
case 011
ZF=1;
case 012
ZF=3;
case 013
ZF=2;
case 014
ZF=4;
case 101
ZF=2;
case 102
ZF=4;
case 103
ZF=1;
case 104
ZF=3;
case 111
ZF=3;
case 112
ZF=2;
case 113
ZF=4;
case 114
ZF=1;
end
%步进电机走步(由ZF控制走步方向由pace控制步长)
switch ZF
case 1
x1=[XM,XM+pace];
y1=[YM,YM];
case 2
x1=[XM,XM-pace];
y1=[YM,YM];
case 3
x1=[XM,XM];
y1=[YM,YM+pace];
case 4
x1=[XM,XM];
y1=[YM,YM-pace];
end
plot(x1,y1,'r-'); %由此点和前一点坐标组成的2个向量画直线
XM=x1(2); %保存此点坐标供下次作图和比较时使用 YM=y1(2);
hold on;
pause(0.01); %延时程序形参为每走一步所用时间end
hold off;。