kuka编程(一):KUKA系统软件(KSS)
本文最后更新于 203 天前,其中的信息可能已经有所发展或是发生改变。

1、KRL程序

1.1程序的结构与建立

1.1.1程序接口

当KRC1软件被安装在目录“KRC:\R1\MADA\”:时,下列文件可作为标准。

File Meaning
$MACHINE.DAT 控制器和机器人的系统数据列表和系统变量
$ROBCOR.DAT 机器人动态模型的系统数据列表和数据
MACHINE.UPG 用于将来升级的系统文件
ROBCOR.UPG 用于将来升级的系统文件

下列文件可在目录“KRC:\R1\SYSTEM\”:下找到

File Meaning
$CONFIG.DAT 系统数据列表和一般数据
BAS.SRC 运动控制的基本软件包
IR_STOPM.SRC 故障时服务功能所使用的程序
SPS.SUB 监视使用的提交文件

1.1.2 文件

KRL程序由SRC和DAT文件组成。

SRC文件包含实际的程序代码,有两个变量:DEFDEFFCT(带返回值)。

DAT文件包含特定的程序数据。它们的区别基于KRL文件概念:除处理顺序不同外,程序包含工业机器人完成的动作也不同。也可能是特殊的运动顺序,打开和关闭夹手,或复杂的顺序,例如有关焊枪限制的控制。

1.1.3文件结构

KRL文件的内部结构由声明部分、指令部分和最多255个局部子程序和函数组成。

DEF NAME(x1:IN)
声明
指令
END  
  • DEF:有的文件不带扩展名,因此在声明中前缀“DEF”。名称最多可包含24个字符,但不允许包含关键字(见[变量和声明]一节)。所有文件以“DEF”开头和“END”结束。
  • 声明 :程序执行前已经检查过声明,即在编译期间检查声明。声明部分不可能有指令,第一个指令开始于指令部分。
  • 指令 与声明不同,指令是动态的,程序处理过程中执行指令。
  • 数据列表 一个机器人程序可能仅包含一个单个的程序文件或一个程序文件和相关的数据表。 数据表和文件具有相同的公共名,区别仅在于扩展名不同。

1.2建立和编辑程序

1.2.1新建程序

Module:包含框架程序的一个SRC文件和DAT文件被创建。
Expert:仅包含标题DEF…和END的一个SRC文件和DAT文件被创建。
Cell:此时,仅创建一个包含SRC的框架程序。该程序用于通过中央PLC控制机器人。
Function:此时,一个包含标题DEF…和END的函数(SRC文件)被创建。
Submit:创建一个SUB文件的框架程序。Submit文件包含可以使用的指令,例如,用于循环监视(夹手等)。Submit文件工作类似于机器人,由控制器解释程序处理。
Expert Submit:使用Submit模板,创建一个SUB文件,这时仅包含标题DEF…和END。

1.2.2 编辑、编译和链接程序

通过菜单“新建”建立一个文件后, 则可以使用编辑器编辑该文件, 可使用软键“编辑”完成该操作。关闭编辑器后,则整个程序代码被编译,也就是说,原文的KRL代码被转换为能让控制器理解的语言。

编译:该处理中,编译器检查代码和语法上的错误,如果检查到错误,则产生对应的消息和拓展名为“.ERR”.的错误文件

链接编辑器:当通过软件“选择”装入一个程序后,建立程序所需要的所有文件和数据表被链接到一起。链接期间,检查模型是否存在,是否已经被编译和存在错误。当传输参数时,编辑器检查所传输参数的类型兼容性。如果链接期间出现错误,则产生扩展名为“.ERR”的错误文件。

您也可以使用一般文本编辑器写一个KRL程序,然后通过“装载”软键装入系统存储器中。这时,您必须确保完成所有的必要的初始化(例如:轴速度) 。

下面的简单程序是一个定义轴速度和加速度的举例
DEF PROG1()
:-----声明部分----
INT J
:------指令部分-------
$VEL_AXIS[1]=100 ;定义轴速度
$VEL_AXIS[2]=100
$VEL_AXIS[3]=100
$VEL_AXIS[4]=100
$VEL_AXIS[5]=100
$VEL_AXIS[6]=100

$ACC_AXIS[1]=100 ;定义轴加速度
$ACC_AXIS[2]=100
$ACC_AXIS[3]=100
$ACC_AXIS[4]=100
$ACC_AXIS[5]=100
$ACC_AXIS[6]=100

PTP{A1 0,A2 -90,A3 90,A4 0,A5 0,A6 0}

FOR J=1 TO 5
PTP {A1 4}
PTP {A2 -7,A3 5}
PTP {A1 0,A2 -9,A3 9}
ENDFOR

PTP {A1 0,A2 -90,A3 90,A4 0,A5 0,A6 0}

END

1.3改变程序

1.3.1程序修改

1.3.2编辑器

1.4隐藏程序部分

缺省时“折合”是“关闭”的,且只能由专家级别用户“打开”,然后用户才可以在KUKA图形用户界面(KUKAGUI)上看见信息。专家级用户在指示范围内装入相关的声明或指令“ FOLD”“ :ENDFOLD”就可以使KRL块让一般用户看见。

通过按菜单键“程序”,然后选择“折合”和需要的命令,可以使程序中的折合显示或隐藏 。

image-20240606195955894

„ Current FOLD opn/cls 打开或关闭编辑光标定位行的折合
„ All FOLDs opn 打开程序的所有折合
„ All FOLDs cls 关闭程序的所有折合

1.4.1 程序举例

DEF FOLDS( )

:FOLD DECLARATION;%附加信息
:---------声明部分--------
EXT BAS (BAS_COMMAND:IN,REAL:IN)
DECL AXIS HOME
INT I
:END FOLD

:FOLD INITIALISATION
:----------初始化--------
INTERRUPT DECL 3 WHEN $STOPMESS==TRUE DO IR_STOPM( )
INTERRUPT ON 3
BAS(#INITMOV,0)初始化速度,
:加速度,$BASE,$TOOL,等
FOR I=1 TO 16
$OUT[I]=FALSE
ENDFOR
HOME={AXIS:A10,A2-90,A390,A40,A530,A60}
:END FOLD

:-------------主程序部分-----------
PTP HOME:BCO运行
LIN{X 540,Y 630,Z 1500,A 0,B 90,C 0}
PTP HOME

END

该举例程序在屏上幕显示如下

image-20240606200050234

打开折合时的显示:

image-20240606200058178

对于编辑器来说“折回”仅仅是一个指令。因为其前面的分号,所以编译器把折合语句看作是一般注释。

1.5程序运行模式

程序运行模式定义如何执行程序

  • 程序不停止

  • 一步一步执行运动指令

  • 单步执行。

    所有的程序运行模式如下表说明

运行模式 说明
GO 执行程序中的所有指令,直到程序结束。
MSTEP 运动步(运动指令) 程序一次执行一个运动指令,也就是说,每个运动指令后插入一个 STOP。 执行的程序不作前置处理。
ISTEP 增量步进(单步) 程序一步一步执行, 也就是说, 每个指令后插入一个STOP(包括空行) 。 执行的程序不作前置处理。
PSTEP 程序单步(程序单步) 子程序被完整地执行。 执行的程序不作前置处理。
CSTEP 连续步进(运动指令) 程序一次执行一个运动指令,也就是说,每个运动指令后插入一个 STOP且精确定位。 执行的程序作前置处理。也就是说,定位为粗定位。

可在KCP上使用状态键或通过变量“$PRO_MODE”选择程序运行模式GO,MSTEP和ISTEP。另一方面,程序运行模式PSTEP和CSTEP只能通过变量“$PRO_MODE”来设置。要修改该状态,首先激活菜单函数“Monitor”-->“Variable”-->“Single”,然后在“名称”的文本输入框中输入变量“$PRO_MODE”和“新值”文本输入框中输入期望的新值。

image-20240606200115063

1.6错误处理

view ERR

使用菜单“监视”→“变量”→“修改”,您可以在线显示错误号的含义。要这样做的话,在状态窗口的“Name”文本输入框中输入字符“$”后跟错误号。本例子中,输入“$2263”,然后按回车键。

image-20240606200152916

jump to

如果现在将SRC文件(“ERROR.SRC”存在的条件下)装入编辑器,您必须进行适当的修改。闪烁光标已经自动定位在包含错误的第一行,使得修改非常方便。确保关闭受限制的可见性和可以看见DEF—行。细节可见[隐藏程序部分]

Refresh

关闭编辑器,存储修改后的文件,按错误列表中的软键“刷新”;如果已经排除完了所有的错误,则错误列表消失。

1.7注释

注释可在程序的任何位置插入。通常在其前面加“:”

2 变量和声明

2.1变量和名称

名称

KRL中的名称

  • 最大长度为24个字符。
  • 可以包含字母(A-Z)、数字(0-9)和符号‘—’和‘$’。
  • 必须以字母开始。
  • 不要使用关键字。

因为所有的系统变量(见2.4节)以符号‘$’开头,所以该符号在自定义名称中不能作为第一个符号。

变量被看作是一个固定的存储器区域,变量的内容可以通过变量名称来寻址。当执行程序时,变量通过存储器位置(地址)和存储器内容(值)来表示。

值分配

使用等号(=)给变量分配值。

不同的数据对象(见节2.2)有不同的存储器需求,所以变量的数据类型在使用前必须声明

变量周期

变量的周期即该时间段内变量在存储器内存在。 取决于变量是在SRC文件或数据表中声明:

SRC文件中声明的变量
周期受程序运行时间的限制。执行完成后存储器区域再分配,则变量值丢失。
数据表中声明的变量 (见数据表一章)
周期与程序运行时间无关,只要该数据表存在,该变量就存在。因此这种变量是永久保持的(直到系统关机)

2.2数据对象

2.2.1数据对象的声明和初始化

DECL:

给一个数据类型分配一个变量名称和保留存储器空间,在KRL中须使用DECL声明来完成。

DECL INT QUANTITY,NUMBER

两个变量QUANTITYNUMBERINTEGER数据类型。
这样编译器就知道这两个变量和相关的数据类型,当使用该变量时,可检查该数据类型是否允许操作。
声明变量,如例子所述,首先是关键字DECL,其后跟的是数据类型分配该数据类型的变量列表

当声明变量和阵列为预定数据类型时,关键字DECL可以省略。不包括简单数据类型INT,REAL,CHAR和BOOL(见2.2.2一节),结构数据类型POS,E6POS,FRAME,AXIS和E6AXIS(见2.2.5一节)是预定的。

对于数据类型是POS的变量(非阵列),声明可以省略。POS数据类型是变量的标准数据类型。
自由可定义结构或列举类型的声明中关键字DECL是包括缺少的。(见节2.2.5和2.2.6)。

初始化

当变量声明完成后,它的值第一次是不可用的,因为根据存储器位置的不同该值可能不同。要使变量可以开始工作,必须预设定一个特定的值。第一次给变量分配值称为初始化。

分配给变量的值是一个指令,因此不要在声明部分出现。初始化,可在指令的任何部分发生。理想状态下,所有声明过的变量应该是在声明部分后的初始化部分直接初始化完成

仅数据表中允许直接在声明行中初始化变量。

image-20240606200233746

2.2.2简单数据类型

数据类型 整数 实数 布尔 字符
关键字 INT REAL BOOL CHAR
含义 整数 浮点数字 逻辑型 1个字符
值的范围 -2^31-2^31-1 +1.1E-38… ±3.4E+38 TRUE,FALSE ASCII字符

INT

如果将一个实数值分配给一个整数型变量,则该值一般被圆整(x.0到.49向下圆整,x.5到x.99向上圆整)。

另外:整数相除的结果从小数点后被切掉,举例:7/4=1

二进制系统 十六进制系统

KRL中可使用反逗号(’)和二进制前缀B或十六进制前缀H表示二进制或十六进制整数。

实数

浮点形式表示,标准格式将一个数字分成固定点部分和一个指数

布尔

布尔变量用于逻辑状态的说明(例如,输入/输出)。值仅有真或假。

字符型

字符型变量可以代表符合ASCII字符规定的一个准确的字符。给一个字符型变量分配的ASCII字符,必须位于括号(”)内。

2.2.3阵列

术语“阵列“指的是相同数据类型对象的组合产生的一个数据对象;通过下标可以寻址阵列中的独立的元素。声明如下
DECL INT OTTO[7]

阵列指针

●阵列可能是任何数据类型。单独的元素也可能有复杂的数据类型(例如,阵列组成的阵列)。
●仅整数型数据类型允许作为下标。
●除常量和变量外,算术表达式也允许作为下标(见节2.3.1)。
●下标起始值通常为1。

2维阵列

除已经讨论过的一维阵列,也就是说仅有一个下标,在KRL中还可以使用两维或三维阵列。采用
DECL REAL MATRIX[7,3]

三维阵列

三维阵列可以看作是一个接一个的一些两维矩阵。第三维指示矩阵所处位置的级别(见图4)。一个三维阵列可简单地声明为一维或两维阵列,例如:
DECL BOOL ARRAY_3D[5,3,4]

2.2.4 字符串

使用字符型数据类型,您仅可以存储一个独立的字符。要使用一串字符,例如字,您只需简单地将一个一维阵列的数据类型定义为字符型:
DECL CHAR NAME[8]

如同通常一样,您可以寻址阵列NAME[ ]中的单个的元素,例如:NAME[3]=”G”

当然,您也可以直接输入全部字符串:NAME[ ]=”ABCDEFG”

2.2.5结构

使用声明语句STRUC,预先定义好的不同数据类型或预定数据类型的组合构成一个新的复合数据类型

STRU

复合使用的一个典型例子是标准数据类型POS。它由文件$OPERATE.SRC中声明的6个实数值和2个整数值组成:
STRUC POS REAL X,,Y,Z,A,B,C,INT S,T

点分离

如果,例如您现在使用结构数据类型的一个POSITION变量,您可以使用分离点给个别的元素分配值:

POSITION.X=34.4
POSITION.Y=-23.2
POSITION.Z=100.0
POSITION.A=90
POSITION.B=29.5
POSITION.C=3.5
POSITION.S=2
POSITION.T=6  

集合

或使用所谓的集合共同分配值:
POSITION={X34.4,Y-23.2,Z100.0,A90,B29.5,C3.5,S2,T6}

● 集合的值可以是简单的常量或它们自己的集合。
● 不是必须在集合中指定结构中的所有组成。
● 成分的指定顺序不必依照它们定义的顺序。
● 集合中每个成分可能只包含一次。
● 在由结构组成阵列的情况下,一个集合定义一个单独的阵列元素的值。
● 结构类型的名称可在一个集合的开头指定-以冒号分开。

对于POS、E6POS、AXIS、E6AXIS和FRAME结构缺少的成分不能被改变。而对于其它集合,则不存在的成分被设置为无效的成分

建立您自己的结构变量的步骤使用下列例子解释:

变量S_PARA必须由3个不同数据类型的元素组成。首先,必须建立一个满足这个要求的新的数据类型:

STRUC WELDTYPE REAL V_WIRE,INT CHARAC,BOOL ARC

建立了一个名称为WELDTYPE的新的数据类型(WELDTYPE不是一个变量!)。WELDTYPE
V_WIRE、CHARAC和ARC三个成分组成。您现在可以任何新数据类型的变量,例如:

DECL WELDTYPE S_PARA

这样您就建立了一个数据类型为WELDTYPE的变量S_PARA。可以通过点分开单独寻址各个成分和通过集合-如上说明来寻址。

为了更容易区分自定义数据类型和变量,新数据类型的名称以…TYPE结束。

预定义结构

image-20240606200426476

几何数据类型

AXIS,E6AXIS,POS,E6POS和FRAME的类型也称为几何数据类型,因为它们提供编程师一个简单的方法用来说明几何关系。

2.2.6列举类型

ENUM

符号

2.3数据处理

2.3.1操作

2.3.1.1算术操作

操作 说明
+ 加法或正号
- 减法或负号
* 乘法
/ 除法

2.3.1.2几何操作

KRL中几何操作以冒号 表示。完成数据类型为FRAMEPOS的操作数的框架联接(逻辑操作)。

框架连接

框架操作是求左和右的值。最右边的结果的数据类型往往是操作数的数据类型(见表5)。

左边操作数(参考CS) 操作 右边操作数(目标CS) 结果
POS POS POS
POS FRAME FRAME
FRAME POS POS
FRAME FRAME FRAME

如果左边的操作数的数据类型是POS,进行类型匹配。POS结构指定的位置被转换为框架。意思是系统检查该位置的刀具框架。

举例

image-20240606200448421

现在的任务就是定义工件坐标系和房间坐标系的相对关系。首先必须先定义下列框架变量:

FRAME TABLE,WORKPIECE,BASE

房间坐标系已经由系统明确地指定。桌子坐标系和工件坐标系现在根据给定的约束初始化。

TABLE={X450,Y600,Z800,A0,B0,C0}
WORKPIECE={X80,Y110,Z55,A-40,B180,C0}

使用几何操作得到工件坐标系和房间坐标系的相对关系

BASE=TABLE:WORKPIECE

在我们的案例中,BASE定义如下:

BASE={X530,Y710,Z855,A140,B0,C-180}
另一个可能是:
BASE={X530,Y710,Z855,A-40,B180,C0}  

2.3.1.3关系操作

操作 说明 允许的数据类型
== 等于 INT,REAL,CHAR,ENUM,BOOL
<> 不等于 INT,REAL,CHAR,ENUM,BOOL
> 大于 INT,REAL,CHAR,ENUM
< 小于 INT,REAL,CHAR,ENUM
>= 大于或等于 INT,REAL,CHAR,ENUM
<= 小于或等于 INT,REAL,CHAR,ENUM

2.3.1.4逻辑操作

操作 操作数数量 说明
NOT 1
AND 2 逻辑与
OR 2 逻辑或
EXOR 2 异或
操作 NOT A A AND B A OR B A EXOR B
A=TRUE B=TRUE FALSE TRUE TRUE FALSE
A=TRUE B=FALSE FALSE FALSE TRUE TRUE
A=FALSE B=TRUE TRUE FALSE TRUE TRUE
A=FALSE B=FALSE TRUE FALSE FALSE FALSE

2.3.1.5位操作

操作 操作数数量 说明
B_NOT 1 一位一位反
B_AND 2 一位一位与
B_OR 2 一位一位或
B_EXOR 2 一位一位异或

2.3.1.6操作优先级

优先级 操作
1 NOT B_NOT
2 * /
3 + -
4 AND B_AND
5 EXOR B_EXOR
6 OR B_OR
7 == <> < > >= <=

2.3.2标准函数

说明 函数 函数的数 据类型 函数值的范围 函数的数 据类型 结果的范围
绝对值 ABS(X) REAL --∞…+∞ REAL 0…+∞
平方根 SQRT(X) REAL 0…+∞ REAL 0…+∞
正弦 SIN(X) REAL --∞…+∞ REAL -1…+1
余弦 COS(X) REAL --∞…+∞ REAL -1…+1
正切 TAN(X) REAL **--∞…+∞*** REAL --∞…+∞
反余弦 ACOS(x) REAL -1…+1 REAL 00…180
反正切 ATAN2(Y,X) REAL --∞…+∞ REAL -900…+900
900的倍数,也就是说.X≠(2k-1)90,K∈N

2.4系统变量和系统文件

所有预定变量的列表见单独资料[系统变量]

计时器

16个计时器变量$TIMER[1]…$TIMER[16]可用于测量时间顺序,可用作“秒表”。开始和停止计时使用系统变量$TIMER_STOP[1]…$TIMER_STOP[16]:

开始计时器4

$TIMER_STOP[4]=FALSE 

关闭计时器4

$TIMER_STOP[4]=TRUE

使用一般变量分配可在任何时候复位有关的计时器变量。举例来说:

$TIMER[4]=0

如果计时器变量值从负向正变化,对应的标记则设置为TRUE(暂停条件),举例来说:

$TIMER_FLAG[4]=TRUE

当控制器启动时,所有的计时器变量预设置为0,标记
$TIMER_FLAG[1]……$TIMER_FLAG[16] 预设置为FALSE

变量$TIMER_STOP[1]……$TIMER_STOP[16] 预设置为TRUE
计时器变量的单位是毫秒(ms)。$TIMER[1]……$TIMER[16]和$TIMER_FLAG[1]……$TIMER_FLAG[16]以12ms循环更新。

标记

1024个标记$FLAG[1]…$FLAG[1024]被用作全局标记。这些布尔变量预设置为FALSE。您可以随时在用户界面上通过“监视”菜单看标记的当前值

循环标记

KRC...中可用32个循环标记$CYCFLAG[1]…$CYCFLAG[32] ,控制器启动后预设为FALSE

$符号

预定变量一般选择一个容易记忆的名称。以$符号开始和有意义的英文缩写组成。

有的预定变量针对整个KRC...控制器(例如$ALARM_STOP用于定义输出到到PLC的急停信号PLC).其它,然而仅用于机器人(例如$BASE用于基本坐标系)。

机器人驱动器中有关控制的数据存储在目录“Steu”中,有关机器人的数据存储在目录“R1”中,并可在KUKA GUI上显示。

image-20240606200519949

在KRC...中还有KUKA定义的和控制软件一起的数据表。这些数据表被称为预定数据表,主要包含预定变量。

$MACHINE.DAT

是预定数据表,包含专有的系统变量。适配控制器和所连接机器人(运动信息,控制参数等)的机床数据。控制系统和机器人系统中都有一个$MACHINE.DAT,您不可以新建或删除现存的。
例如:

$ALARM_STOP 急停信号 (控制器特有)
$NUM_AX 机器人轴数 (机器人特有)

$CUSTOM.DAT

仅在控制系统中存在的数据表。包含可以配置或参数化特定控制函数的数据。编程师仅可以改变预定变量的值。不可以新建或删除现存的。例如:

$PSER_1 串行接口1的协议参数
$IBUS_ON 激活可选的联络母线组

$CONFIG.DAT

KUKA预定的数据表,不包含任何系统变量,然而,在控制级和机器人级都有一个$CONFIG.DAT可用。其中可定义长时间有效的变量、结构、通道和信号,对许多程序普通重要。
数据表分为以下几个程序块:

-- BAS
-- AUTOEXT
-- GRIPPER
-- PERCEPT
-- SPOT
A10
A50
A20
-- TOUCHSENSE
-- USER  

用户的全局声明应该输入USER程序块,因为仅该处的声明在以后的软件升级中被转移。

$ROBCOR.DAT

文件$ROBCOR.DAT包含特定机器人的机器人动态模型的数据。在轨迹计划编排中需要这些数据。在文件中您不可以新建一个新变量或删除现存的。

3运动编程

3.1不同坐标系的应用

最基本的坐标系时连接(轴指定)坐标系和笛卡尔坐标系

KRC...中定义的角度A、B和C是绕坐标轴Z、Y和X的旋转角度。旋转的顺序必须保留。

  1. 绕Z轴的旋转角度为A
  2. 绕Y轴的旋转角度为B
  3. 绕X轴的旋转角度为C

这个旋转顺序与众所周知的航空领域的roll--pitch—yaw角度一致。角度C对应于roll,角度B对应于pitch,角度A对应于yaw。

KRC...中预定了下列笛卡儿坐标系

坐标系 系统变量 状态
全局坐标系 $WORLD 写保护
机器人坐标系 $ROBROOT 写保护(可在 R1/MADA/$MA CHINE.DAT中改 变)
工具坐标系 $TOOL* 可写
基本(工件)坐标系 $BASE* 可写

image-20240606200613659

world坐标系

全局坐标系是固定的(=当机器人移动时坐标系不动)坐标系,用作机器人系统(机器人、支撑部分或工具)的根本坐标系。是机器人系统和单元外围装备的参考系统。

机器人坐标系

机器人坐标系位于机器人底部,是机器人机械结构的参考坐标系。起源于全局坐标系且当机器人系统交货时机器人坐标系与全局坐标系一致。与$WORLD的偏置关系可使用$ROBROOT定义。

工具坐标系

工具坐标系的原点在刀尖上。可以以下列方法选择方位,坐标系的X轴与工具的工作方向一致,X轴的方向远离工具。工具坐标系随工具的移动而移动

基坐标系

基坐标系是用来定义工件位置的参考坐标系。机器人在基坐标系中编程,全局坐标系作为它的参考坐标系。在交货时,$BASE=$WORLD。可以改变$BASE,例如当使用相同的程序加工不同位置的许多相同的工件时。

3.2点到点运动PTP

PTP:点到点运动是将刀尖(刀具中心点:TCP)从当前位置移动到编程终点位置的最快方法。控制器计算各轴必要的角度差别。

3.2.1一般说明

使用下列系统变量:
$VEL_AXIS[轴数]:编程的最大轴速度
●$ACC_AXIS[轴数]:编程的最大轴加速度
机床数据中所有的输入以最大值的百分比给定。对于所有轴来说,如果还没有编程这两个系统变量,执行程序则会产生相关的错误消息。

由于在笛卡儿坐标系中的PTP运动通常不知道哪一个轴是主导轴,所以明智的做法是将所有轴设置同样的加速度和速度值。

3.2.2更高级的运动轮廓

3.2.3运动命令

程序中首先定义轴的速度和加速度,必须在执行点到点运动前分配这些值

DEFPTP_AXIS( ) ;程序名是PTP_AXIS
$VEL_AXIS[1]=100 ;定义轴速度
$VEL_AXIS[2]=100
$VEL_AXIS[3]=100
$VEL_AXIS[4]=100
$VEL_AXIS[5]=100
$VEL_AXIS[6]=100

$ACC_AXIS[1]=100 ;定义轴加速度
$ACC_AXIS[2]=100
$ACC_AXIS[3]=100
$ACC_AXIS[4]=100
$ACC_AXIS[5]=100
$ACC_AXIS[6]=100
PTP{AXIS:A1 0,A2 –90,A3 90,A4 0,A5 0,A6 0}
END

PTP

PTP{A3 45}  

PTP指令中定义的角度值是绝对值。因此机器人并不是旋转45度,而是旋转到45度。

PTP_REL

相对运动,使用指令PTP REL。例如要旋转轴1和4都是35度,简单编程如下:

PTP REL PTP REL {A1 35,A4 35}  

通过POS结构在笛卡儿坐标系中输入值,如同下面的举例:

DEF PTP_POS( )

$BASE=$WORLD ;设置基本坐标系

$TOOL=$NULLFRAME  ;设置工具坐标系

$VEL_AXIS[1]=100 ;定义轴速度
$VEL_AXIS[2]=100
$VEL_AXIS[3]=100
$VEL_AXIS[4]=100
$VEL_AXIS[5]=100
$VEL_AXIS[6]=100

$ACC_AXIS[1]=100 ;定义轴加速度
$ACC_AXIS[2]=100
$ACC_AXIS[3]=100
$ACC_AXIS[4]=100
$ACC_AXIS[5]=100
$ACC_AXIS[6]=100

PTP{POS:X 1025,Y 0,Z 1480,A 0,B 90,C 0,S ’B010’,T ’B000010’}
END

坐标系

笛卡儿坐标系中使用几何操作可以直接在运动命令中进行框架联接,这种方法,例如可以不修改系统变量$BASE而初始化与基本坐标系的偏置。

而且,通过冒号操作指定一个基本偏置比重新定义$BASE更有优势:运动指令中出现偏置操作,则必须在运动指令前设置$BASE。以该方法,即使停止了程序后选择后续的程序段,运动总是选择了正确的基本坐标系。

因此, $BASE 和$TOOL 仅可以被设置一次,例如,在程序的初始化部分。然后可以使用几何操作进行后续的偏置。

INI

在这个例子中,速度和加速度及$BASE和$TOOL坐标系的分配不是“手动”进行,而时由标准基本软件包中的“BAS.SRC”来完成,要这样做,必须首先使用EXT指令使程序认识。
初始化命令

INI BAS(#INITMOV,0)

然后分配缺省值给所有重要的系统变量。

BCO

明智的做法是编程一个“Home”作为第一个运动指令;移动机器人到一个明确定义的位置,这样就确立了程序段一致性。机器人在程序的结束应返回该位置。

S和T

POS定义中的“S”和“T”用于选择一个特定的, 明确定义的空间中需要许多轴定位的同一个点的机器人位置 。

程序的第一个运动指令必须总是一个定义了状态和转的完整的PTP指令(或一个完整的使用轴坐标系的PTP指令)。在后续的PTP指令中,只要不需要特定轴定位,例如要要避开障碍时可以省略“S”和“T”,机器人保持最短轴轨迹使用的S和T值,则在第一个PTP指令中编程 “S”和 “T”后,每次程序运行时,机器人的轨迹都相同 。

Turn

属性包含“Turn”属性的扩展笛卡儿位置,可以在不需要特殊移动策略(例如辅助点)时,轴的移动角度大于+1800或小于-1800。对于旋转轴,轴值前面的各位决定符号,如下:
位x=0:轴的角度 ≥00
位x=1:轴的角度<00

值T‘B10011’意思是指轴1、2、5的角度是负值,而轴3、4、6是正值(高位是0可以省略)。

Status

状态S当轴位置不明确时使用(见图18)。S根据当前机器人运动系统的不同而不同

3.3连续轨迹运动(CP运动=连续轨迹)

3.3.1速度和加速度

与PTP运动不同,在连续轨迹运动中不是只定义起点和终点,还需要定义这些点之间沿直线和圆弧轨迹的TCP运动。
输入的速度和加速率对于单独的轴或TCP的运动不再有关系,对于平移运动、旋转角和旋转的角度必须编程速度和加速度

image-20240606200643554

当调用基本软件包的初始化顺序时,CP运动的缺省设置速度和加速率也被预设为机床数据$CONFIG.DAT定义的最大值。
CP运动的轴速度和加速度被监视,监视范围在系统变量$ACC_ACT_MA和$VEL_ACT_MA定义,如果超过该范围,则触发制动反应,同时产生错误消息。标准范围是法向轴加速度的250%和法向轴速度的110%。这些监控范围对所有操作模式和手动移动都有效。要预防超过监控范围引起的反应(制动反应),可以使用系统变量$CP_VEL_TYPE降低轴进给速、加速度和速度。该变量的缺省设置是#CONSTANT,I也就是说,在程序模式降速是不激活的。如果要在T1模式(T1模式使用更低的速度和加速度)使用该功能,必须设置值#VAR_T1,而对于所有操作模式则要设置值#VAR_ALL。在JOG模式总是激活降速。在测试模式如果降低轨迹速度,系统变量$CPVELREDMELD会产生错误消息,要这样做的话,必须分配该值为“1”。

3.3.2方位控制

如果轨迹运动期间,要改变工具在空间中的方位,可以使用系统变量$ORI_TYPE设置为方位控制模式(见图21):

$ORI_TYPE=#CONSTANT 轨迹运动期间方位保持不变;对于使用的起点和终点,编程的方位被忽略。
$ORI_TYPE=#VAR 轨迹运动期间从最初的方位到最终的方位,方位连续变化。 该值在初始化期间通过BAS(#INITMOV,0)来设置。

image-20240606200703318

对于圆弧运动, 固定的和变化的方位外,还需要选择空间相关的方位和轨迹相关的方位

$CIRC_TYPE=#BASE 在圆弧运动期间执行空间相关的方位控制。该值也要在初始化期间通过BAS(#INITMOV,0)来设置。
$CIRC_TYPE=#PATH  在圆弧运动期间执行轨迹相关的方位控制。

固定方位+轨迹相关

image-20240606200718732

变化的方位+轨迹相关

image-20240606200730772

固定方位+空间相关

image-20240606200740842

变化的方位+空间相关

image-20240606200751160

3.3.3线性运动

LINE

使用关键字LIN或LIN_REL及终点定义来编程一个线性运动,类似于PTP编程。线性运动的终点以笛卡儿坐标输入。仅允许使用数据类型FRAME或POS .

CIRCLE

要明确地定义空间中的一个圆和圆弧运动,需要互相不在一条直线的三个不同点。圆弧运动的起点也是当前位置,同PTP中的LIN。

CONTINUE

3.5使用逼近定位的运动

5.程序执行控制

5.1程序分支

5.1.1跳跃分支

GOTO

5.1.2条件分支

IF

结构化的IF语句允许使用选择两个选项之一的公式化的指令。该指令的一般形式是:

image-20240606200810080

执行条件是布尔表达式。如果满足执行条件则执行THEN程序段。如果不满足则可以执 行ELSE程序段或省缺。如果省缺,则立即离开分支。

可以使用一个不受次数限制的指令。特别是可以使用深一层的IF语句。IF程序段的嵌 套是允许的。但是每一层的IF语句必须以自己的ENDIF结束。

在下列程序中,如果输入10为FALSE,机器人将移动到HOME位置。如果输入10被设置 且变量A的值大于变量B的值,则输出10被设置,机器人移动到点1。与A和B无关,只 要输入1被设置,变量A的值就会增加1,机器人运动到HOME位置:

… 
INTA,B 
… 
IF $IN[10]==FALSE THEN 
PTP HOME 
ELSE 
IF A>B THEN 
$OUT[1]=TRUE 
LINPUNKT1 
END IF 
A=A+1 
PTP HOME 
END IF 
…

5.1.3转换

SWITCH

SWITCH语句是用于不同程序分支的选择指令。选择的标准是SWITCH语句前分配的值。 如果该值与程序段标识符一致,则执行对应的分支,程序直接跳跃到ENDSWITCH语句 而不考虑后面程序段的标识符。

如果没有程序段标识符与选择标准一致,就执行 DEFAULT语句程序段,如果有一个。否则,程序从ENDSWITCH后的指令重新开始执行。 一个程序分支可以分配许多程序段标识符。另一方面,一个程序段标识符使用许多 次则是不明智的,因为仅考虑对应标识符的第一个分支。

选择标准允许的数据类型是INT,CHAR和ENUM。选择标准的数据类型必须与程序段标 识符一致。

可以省略DEFAULT语句,且在SWITCH语句内仅可以出现一次。 SWITCH语句可以用于,例如,通过程序号调用不同的子程序。程序号也可以,例如 用于KRC..中PLC的数字输入(见节6.3有关SIGNAL语句的信息)。以该方法,作为整 数值用作选择标准。

DEF MAIN()
…
SIGNAL PROG_NR $IN[1] TO $IN[4];期望的程序号现在通过PLC存储在INT变量PROG_NO中
…
SWITCH PROG_NO
    CASE 1 ;如果PROG_NO=1
        PART_1()
    CASE 2 ;如果PROG_NO=2
        PART_2()
        PART_2A()
    CASE3,4,5 ;如果PROG_NO=3,4或5
        $OUT[3]=TRUE
        PART_345()
    DEFAULT ;如果PROG_NO<>1,2,3,4或5
        ERROR_UP()
ENDSWITCH
…
END

5.2循环

5.2.1计数循环

FOR

image-20240606200836178

计数器中输入整数类型的表达式作为Start和End的值。 循环开始时对该表达式求值。

以起始值预先定义整数型变量Counter(必须提前声明) ,然后该值在每次循环执行后增加或减少编程的增量。

Increment既不能是一个变量,也不能是零。如果没有指定增量,则使用缺省值1。允许使用负的增量值。

每个FOR语句必须以一个ENDFOR语句结束。

在下面的例子中,首先设置轴速度$VEL_AXIS[1]...$VEL_AXIS[6]为100%。然后使用 计算出的值初始化二维阵列的组件。

DEF 
FOR_PROG( ) 
... 
INT I,J 
INT ARRAY[10,6] 
... 
FOR I=1 TO 6 
$VEL_AXIS[I]=100  ;所有轴速设置到100%
ENDFOR 
... 
FOR 
I=1TO 9 STEP2 
FOR J=6 TO 1 STEP –1 
ARRAY[I,J]=I*2+J*J 
ARRAY[I+1,J]=I*2+I*J 
ENDFOR 
ENDFOR    ;现在I的值为11,J的值为0 
... 
END 

5.2.2跳出循环

WHILE

WHILE循环在重复开始时请求一个执行条件。它是一个跳出循环,它不是单次运行,直到开始设置的执行条件满足时才跳出。WHILE循环语法如下:

image-20240606201154892

执行条件是一个逻辑表达式,可以是一个布尔变量、一个布尔函数调用或一个布尔结 果的逻辑操作。

逻辑操作的值为TRUE时执行指令程序段,也就是说满足执行条件。逻辑操作的值为 FALSE时程序从ENDWHILE后的下一个指令重新开始。因此每个WHILE语句必须以 ENDWHILE语句结束。

DEF WHILE_PR() 
... 
INT X,W 
... 
WHILE $IN[4]==TRUE  
PTP PALLET 
$OUT[2]=TRUE 
PTP POS_2 
$OUT[2]=FALSE 
PTP HOME 
ENDWHILE 
... 
X=1 
W=1 
WHILE W<5;    
X=X*W 
W=W+1 
ENDWHILE 
... 
W=100 
WHILE<W100    
$OUT[15]=TRUE 
W=W+1 
ENDWHILE 
... 
END 

5.2.3非一跳出循环

REPEAT

与WHILE循环相对应的是REPEAT循环。 REPEAT,直到循环结束时才检查结束条件。因 此REPEAT循环总是运行一次,即使在循环开始前结束条件已经满足。

image-20240606201248295

5.2.4无穷循环

只能使用EXIT语句结束指令程序段的重复执行

image-20240606201259768

5.2.5循环的退出

使用EXIT语句可以提前结束任何循环。通过在循环的指令程序段内调用EXIT,循环运行立即结束,程序在循环结束语句后重新开始。

在REPEAT和WHILEl循环中选择合理的结束和执行条件而不必主要依靠使用EXIT语句。但是对于无穷循环,仅可以使用EXIT结束循环的执行。

5.3等待指令

5.3.1等待一个事件

image-20240606201311768

如果在调用WAIT时逻辑表达式条件已经为TRUE,则不会停止程序的执行(但是触发提前运行停止)。
如果条件为FALSE,则停止执行程序直到表达式的值为TRUE才继续执行程序。

数字值

WAIT FOR... 消息窗口中的消息 含义
$IN[5] Waiting for input5 等待直到输入5为TRUE
$OUT[5]==FALSE Waiting for not output5 等待直到输入5为FALSE
$TIMER[5]>=300 Waiting until timer5>=300 等待直到计时器5至少达到 300ms
$TIMER_FLAG[5] Waiting for Timer_Flag5 等待直到计时器标志5为TRUE
$FLAG[5]==FALSE Waiting for not flag5 等待直到标志5为FALSE
$CYCFLAG[5] Waiting for cyclical flag5 等待直到循环标志5为TRUE
I[5]==9 Waiting for counter5==9 等待直到计时器5的值等于 “9

变量值

一个变量被转换为一个数字。该变量必须在数据表(.dat)中声明。在源文件(.src)中的声明则是定义该变量的值。

数据表:            源文件:
DEFDAT PROG1      DEF PROG1( )
…                 …
DECL INT          INT VAR INT VAR=7
…                 …

长文本

信号声明

5.3.2 等待时间

WAIT SEC语句允许使用秒来编程等待时间:

image-20240606201354778

5.4停止程序

HALT 如果要中断程序执行和停止处理,编程如下指令

image-20240606201403088

5.5 确认消息

image-20240606201410413

6 输入输出指令

6.1一般说明

KRC…可以识别1026个输入和1024个输出。在标准的KUKA控制柜中,用户可以使用X11连接器的下列输入和输出(MFC模块):
输入 1…16

其它输入/输出可以随意配置,例如使用区域总线。
可以读输入和写输出。它们通过系统变量$IN[No]或$OUT[No]寻址。未使用的输出可以当作标记使用。
MFC模块可在文件“ IOSYS.INI”重新分配输入/输出。

7.子程序和函数

7.1声明

DEF

所有的子程序与主程序的声明方法一样,使用DEF声明加上名字,以END结束,举例说明:

image-20240606201453189

DEFFCT

函数是子程序类型中的一种;不同的是,程序名同时也是一个指定数据类型的变量。函数的结果可以通过简单地给变量分配一个值来传递。因此,当使用关键字DEFFCT声明函数时,函数的数据类型和函数的名字都要指定。函数以ENDFCT指令结束。因为函数假设为传递一个值,所以必须在ENDFCT语句前使用RETURN语句指定该值。例子:

DEFFCT INT FUNCTION()
…
RETURN(X)
ENDFCT  

局部函数

主程序和子程序或函数在同一个SRC文件中。该文件与主程序名相同。

全局函数

全局子程序和函数以单独的SRC文件存储。以该方法,则如果被其它程序调用,则每个调用的程序都变成了子程序

有在主程序的数据表中声明过的变量都可以在子程序和函数中被识别。主程序(SRC文件)中已经声明过的变量称为“ runtime变量”,仅可以在主程序中使用。试图在子程序中使用这些变量会产生相应的错误消息。
主程序中声明过的变量也不能在全局子程序和函数中被识别。
子程序或函数中声明过的变量在主程序中不能被识别。
主程序不能存储其它主程序的局部子程序和函数。
局部子程序/函数名的最大长度是24个字符。全局子程序/函数名的最大长度是20个字符(由于有文件扩展名)。

image-20240606201509531

7.2子程序和函数的调用和参数传递

通过输入子程序名加上圆括号调用子程序。

SUBPROG1()  

参数表

值调用(IN)

参考调用(OUT)

image-20240606201535954

在子程序或函数中通过在参数表的每个变量后输入关键字IN输入“通过值调用”。通过输入字OUT得到 “通过参考调用”,OUT也是缺省设置。例如:

DEF CALCULATE(X:OUT,Y:IN,Z:IN,B)  

当传输一个阵列时,在子程序和函数中也必须声明该阵列,但是没有索引。

8中断处理

8.1声明

INTERRUPT

可能产生中断的原因和系统将对它们采取的措施,必须在中断可以被激活前定义好。
INTERRUPT 使用中断声明完成该操作,给每个中断分配一个优先级、事件和调用的中断程序。完整的语句是:

image-20240606201644281

自变量 数据类型 含义
Priority INT 指定中断优先级的算术表达式,可以使用的优先级为 1…39和81…128。 值40…80为机器人系统的自动优先级分配保留。
Event BOOL 定义中断事件的逻辑表达式。下列是允许的: 一个布尔常数 一个布尔变量 一个信号名 一个比较
Subprogram 当事件发生时要执行的中断程序的名字

中断声明是一条指令,因此, 千万不要在声明部分中使用。

  • 一个声明可能在任何时候被另一个声明重写。
  • GLOBAL中断不同于一般的中断,即使声明的子程序在左边仍然保持有效。
  • 一次最多可以声明32个中断。
  • 在中断条件下不能存储结构变量和成分。
  • 除GLOBAL变量和数据表中声明的变量外,实时变量不能当作中断程序参数被传输。

image-20240606201656258

8.2中断的激活

打开中断

INTERRUPT ON 4  开优先级为4的中断  
INTERRUPT ON    开所有中断

边缘触发

检查是边缘触发型的,也就是说一个中断仅在逻辑条件从FALSE状态变化为TRUE状态时被 触发,反之如果当开中断时条件已经是TRUE则不触发。

关闭中断

与开的方法相同,中断可以单独或所有一起被关:
INTERRUPT OFF 4
或
INTERRUPT OFF  

禁止/使能

使用关键字ENABLE和DISABLE,已经打开的中断可以被单独或全部使能或禁止。
禁止命令可以在被中断前保护程序的某些部分。一个禁止的中断可以被识别和存储,但是不能被执行。仅当被使能后,已经发生的中断才以它们的优先级顺序被执行。

DISABLE 4
或
DISABLE

触发一个中断的前提条件是:
●中断必须是声明过的( INTERRUPT DECL…)
●中断必须被打开( INTERRUPT ON)
●中断必须是没有被禁止的
●对应的事件必须已经发生(边缘触发)

优先级

8.3停止现在的运动

如果必要的话, 在中断程序中使用BRAKE语句,则可以在中断事件中停止已经正在执行的机器人的运动

BRAKE  

BRAKE 指令仅可以在中断程序中使用, 在其它程序中使用则会导致一个错误引起的停止。

8.4取消中断事务

KRC...中机器人运动的取消是可能的,使用语句:

RESUME

RESUME可以取消当前中断被声明的级别和以下级别的所有运行的中断程序和子程序。

同 BRAKE 语句,RESUME 仅允许在中断程序中使用。当激活 RESUME 语句时,提前运行指针千万不要在中断被声明的级别,至少应低一个级别。

8.5循环标记的使用

在中断声明指令中不允许使用逻辑操作因此,要定义复杂的事件,您必须使用使用程序如下;

$CYCFLAG[3]=$IN[1] AND([$IN[2] OR $IN[3])
INTERRUPT DECL 10 WHEN $CYCFLAG[3] DO IR_PROG()
INTERRUPT ON 10

您可以同时监视和逻辑组合3个输入。

9 触发轨迹相关的开关动作

9.1在轨迹的起点或终点开关动作

TRIGGER

如果需要一个与运动轨迹起点或终点相关的开关动作,在相关的运动指令(PTP,LIN 或CIRC)前,以下列语法编程一个TRIGGER语句:

image-20240606201727429

自变量 数据类型 含义
Switching point INT 对于单独的程序段, DISTANCE=0指明为下一个运动 的起点,属性DISTANCE=1则为终点。 对于逼近程序段, DISTANCE=1表示后续逼近定位圆 弧的中点。如果前一个程序段也 是一个逼近程序段, DISTANCE=0表示前述逼近定位 圆弧的终点。
Time INT 使用属性DELAY,可以延迟或提前开关动作某些时 间。 开关点仅可以在有关程序段保持有效时被延迟 或提前。 单位是毫秒。
Instruction 指令可以是 一个子程序调用 变量值的分配 一个输出指令(也可以是脉冲)。
Priority INT 使用子程序调用的每个TRIGGER语句必须定义一个 优先级。允许值为1...39和81...128。 优先级的使用与中断中的一样。(见章8)。 值40...80为机器人自动优先级分配保留。如果要 使用,编程PRIO=-1。

9.2在轨迹的任何点开关动作

TRIGGER

如果您正在使用轨迹相关的TRIGGER语句,则可以通过指定一个距离在沿轨迹的任何 位置触发开关动作,与在起点和终点的开关动作一样,也可以被延迟或提前。

轨迹相关的开关动作仅允许在连续轨迹运动(PTP,LIN或CIRC)中使用。这儿的触发 语句指的是下一个编程运动,语法如下:

image-20240606201758383

自变量 数据类型 含义
Distance INT 触发后, 您可以在从编程的终点起指定一个期望的 距离。 如果该终点是一个被逼近的点, 指定开关动作的期 望距离从逼近定位范围中紧靠终点位置算起。 通过指定一个负的距离, 开关点可以最远被移回到 起点。如果该起点是一个逼近定位点,开关点可以 最远被移到逼近定位范围的起点。 通过指定一个正的距离, 则最远移到编程的下一个 精确定位点 单位是毫米。
Time INT 使用属性DELAY,可以延迟(+)或提前(-)轨迹中开 关点某些时间。 开关点仅可以在上述给定(最远到下一个精确定位 点)开关范围内被延迟或提前。逼近定位运动中。 开关点至多可以被提前到开始逼近定位的起点。 单位是毫秒。
Instruction 指令可以是 一个子程序调用 变量值的分配 一个输出指令(也可以是脉冲)。
Priority INT 使用子程序调用的每个TRIGGER语句必须定义一个 优先级。允许值为1...39和81...128。 优先级的使用与中断中的一样。(见章8)。 值40...80为机器人自动优先级分配保留。如果要 使用,编程PRIO=-1。

9.3触发语句重叠

  • 手动给两个触发语句分配各自的优先级;
  • 分配两个触发语句的优先级都为“--1”,然后由系统自动分配正确的优先级。

10 数据表

10.1局部数据表

数据表用于特殊编程准备和更高级别声明。包含点的消息,例如坐标:
●一个数据表可能为每个SRC文件草拟。数据表与SRC文件具有相同的文件名并以“.DAT”作为扩展名。
●数据表仅可能由声明和初始化组成。
● 一行由声明和初始化组成。
●不接受系统变量。

DEFDAT

数据表的声明类似于SRC文件的声明:声明以关键字DEFDAT和文件名开始,以关 键字ENDDAT结束。

image-20240606201811945

在数据表中允许使用下列声明:
● SRC文件中使用子程序和函数的外部声明。
● 导入变量的导入声明。
● SRC文件中使用变量的声明和初始化。
● SRC文件中使用信号和通道名的声明。
● 数据表或SRC文件中使用数据的声明和列举类型( Struc,Enum)。

10.2全局数据表

数据表中定义的变量可被“别的”主程序接受 。

PUBLIC

数据表必须在开头行以关键字PUBLIC定义为“公共可接受”。

如果要使用变量OTTO,从以上数据表PROG_1中导入到PROG_2(),可以在PROG_2()中编程下列导入声明,与数据表中的关键字PUBLIC一样:

IMPORT INT OTTO_2 IS /R1/PROG_1..OTTO

目录/R1下的数据表PROG_1.DAT中的变量OTTO现在是程序PROG_2()中的OTTO_2

![image-20240606201832436](C:\Users\Lei Ting\AppData\Roaming\Typora\typora-user-images\image-20240606201832436.png)

GLOBAL

变量被声明为“全局变量”,例如DECL GLOBAL INTOTTO=0,可不使用导入命令而被所有别的主程序接受。
如果一个全局变量已经被声明,就不能在别的主程序中改变该全局变量名。

image-20240606201919436

仅允许在数据表中声明全局变量。 如果要在SRC或SUB文件中声明, 则会产生错误消息。

对许多程序有用的长时间有效的、一般意义的变量、结构、通道和信号可以提前定义在$CONFIG.DAT中

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇