以下文章来源于不知名网友i ,作者不知名网友i
软件支持
库卡软件包支持:
需要KUKA.Ethernet KRL,具体小版本根据系统而定。
测试环境:
虚拟机:VM17Pro
示教器:Officelite v8.6.7
编程:Workvisual v6.3.0
电脑:w11 python(测试) socketTool(测试)
配置方法
库卡 socket 一切关于 socket 配置的操作,都基于一个或多个 xml 文件。

软件安装后自带的一些 demo 和文档,本文不过多概述。
关于 xml 文件的参数解析:
基于VST_Ethernet_KRL_31_zh,文中未提及的皆为可选参数,具体请参阅手册
连接

Server 192.1.10.20 54600 TCP
接收数据
发送数据
实战起!
我的 xml 文件,作用:接收位置数据并只回复状态。
192.168.0.1 59152

关于EKI的一些函数
程序说明:
1、接收上位机发送的 xyz 位置变量,欧拉角使用当前自身位置,得到后赋值到位置变量数组。DECL FRAME POS_DATA[1000]位置变量声明于 config 中。

SRC

DAT
&ACCESS RVP
DEF RECE_MAIN ( )
;FOLD INI;%{PE}
;FOLD BASISTECH INI
GLOBAL INTERRUPT DECL 3 WHEN $STOPMESS==TRUE DO IR_STOPM ( )
INTERRUPT ON 3
BAS (#INITMOV,0 )
;ENDFOLD (BASISTECH INI)
;FOLD USER INI
;Make your modifications here
;ENDFOLD (USER INI)
;ENDFOLD (INI)
;FOLD SPTP HOME Vel=100 % DEFAULT ;%{PE}
;FOLD Parameters ;%{h}
;Params IlfProvider=kukaroboter.basistech.inlineforms.movement.spline; Kuka.IsGlobalPoint=False; Kuka.PointName=HOME; Kuka.BlendingEnabled=False; Kuka.MoveDataPtpName=DEFAULT; Kuka.VelocityPtp=100; Kuka.VelocityFieldEnabled=True; Kuka.CurrentCDSetIndex=0; Kuka.MovementParameterFieldEnabled=True; IlfCommand=SPTP
;ENDFOLD
SPTP XHOME WITH $VEL_AXIS[1] = SVEL_JOINT(100.0), $TOOL = STOOL2(FHOME), $BASE = SBASE(FHOME.BASE_NO), $IPO_MODE = SIPO_MODE(FHOME.IPO_FRAME), $LOAD = SLOAD(FHOME.TOOL_NO), $ACC_AXIS[1] = SACC_JOINT(PDEFAULT), $APO = SAPO_PTP(PDEFAULT), $GEAR_JERK[1] = SGEAR_JERK(PDEFAULT), $COLLMON_TOL_PRO[1] = USE_CM_PRO_VALUES(0)
;ENDFOLD
ACT_POS = $POS_ACT
INIT_DATA()
GET_DATA()
;wait until data read
RET=EKI_Close("XmlCallBack")
RET=EKI_Clear("XmlCallBack")
RUN_ROBOT()
END
DEF INIT_DATA()
RET=EKI_Init("XmlCallBack")
RET=EKI_Open("XmlCallBack")
RET = EKI_SEND("XmlCallBack", "Status 200")
; INIT
save_index = 1
FOR i=1 TO (1000)
POS_DATA[i]={X 0.0,Y 0.0,Z 0.0,A 0.0,B 0.0,C 0.0}
ENDFOR
valueFrame={X 0.0,Y 0.0,Z 0.0,A 0.0,B 0.0,C 0.0}
END
DEF GET_DATA()
LOOP
Wait for $Flag[1]
;SET_VALUE
RET=EKI_GetFrame("XmlCallBack","Sensor/Read/xyzabc",valueFrame)
IF (valueFrame.X <> 666.666) and (valueFrame.Y <> 666.666) THEN
POS_DATA[save_index] = valueFrame
POS_DATA[save_index].A = ACT_POS.A
POS_DATA[save_index].B = ACT_POS.B
POS_DATA[save_index].C = ACT_POS.C
save_index = save_index + 1
$Flag[1]=False
ELSE
EXIT
ENDIF
RET = EKI_SEND("XmlCallBack", "Status 200")
ENDLOOP
END
DEF RUN_ROBOT()
DECL FRAME XMOVE_POS
LOOP
FOR i=1 TO (1000)
XMOVE_POS = POS_DATA[i]
;FOLD SLIN MOVE_POS Vel=2 m/s CPDAT1 Tool[1] Base[0] ;%{PE}
;FOLD Parameters ;%{h}
;Params IlfProvider=kukaroboter.basistech.inlineforms.movement.spline; Kuka.IsGlobalPoint=False; Kuka.PointName=MOVE_POS; Kuka.BlendingEnabled=False; Kuka.MoveDataName=CPDAT1; Kuka.VelocityPath=2; Kuka.VelocityFieldEnabled=True; Kuka.ColDetectFieldEnabled=True; Kuka.CurrentCDSetIndex=0; Kuka.MovementParameterFieldEnabled=True; IlfCommand=SLIN
;ENDFOLD
SLIN XMOVE_POS WITH $VEL = SVEL_CP(2.0, , LCPDAT1), $TOOL = STOOL2(FMOVE_POS), $BASE = SBASE(FMOVE_POS.BASE_NO), $IPO_MODE = SIPO_MODE(FMOVE_POS.IPO_FRAME), $LOAD = SLOAD(FMOVE_POS.TOOL_NO), $ACC = SACC_CP(LCPDAT1), $ORI_TYPE = SORI_TYP(LCPDAT1), $APO = SAPO(LCPDAT1), $JERK = SJERK(LCPDAT1), $COLLMON_TOL_PRO[1] = USE_CM_PRO_VALUES(0)
;ENDFOLD
IF (POS_DATA[i + 1].X == 0) AND (POS_DATA[i + 1].Y == 0) THEN
EXIT
ENDIF
ENDFOR
ENDLOOP
END
&ACCESS RVP
DEFDAT rece_main
;FOLD EXTERNAL DECLARATIONS;%{PE}%MKUKATPBASIS,%CEXT,%VCOMMON,%P
;FOLD BASISTECH EXT;%{PE}%MKUKATPBASIS,%CEXT,%VEXT,%P
EXT BAS (BAS_COMMAND :IN,REAL :IN )
DECL INT SUCCESS
;ENDFOLD (BASISTECH EXT)
;FOLD USER EXT;%{E}%MKUKATPUSER,%CEXT,%VEXT,%P
;Make your modifications here
;ENDFOLD (USER EXT)
;ENDFOLD (EXTERNAL DECLARATIONS)
INT i, save_index
DECL EKI_STATUS RET
FRAME ValueFrame
DECL E6POS ACT_POS
DECL MODULEPARAM_T LAST_TP_PARAMS = {PARAMS[] "Kuka.VelocityFieldEnabled=False; Kuka.ColDetectFieldEnabled=False; Kuka.MovementParameterFieldEnabled=False; Kuka.IsAngleEnabled=False; Kuka.PointName=MOVE_POS; Kuka.FrameData.base_no=0; Kuka.FrameData.tool_no=1; Kuka.FrameData.ipo_frame=#BASE; Kuka.isglobalpoint=False; Kuka.MoveDataName=CPDAT1; Kuka.MovementData.cb={AUX_PT {ORI #CONSIDER,E1 #CONSIDER,E2 #CONSIDER,E3 #CONSIDER,E4 #CONSIDER,E5 #CONSIDER,E6 #CONSIDER},TARGET_PT {ORI #INTERPOLATE,E1 #INTERPOLATE,E2 #INTERPOLATE,E3 #INTERPOLATE,E4 #INTERPOLATE,E5 #INTERPOLATE,E6 #INTERPOLATE}}; Kuka.MovementData.apo_fac=50; Kuka.MovementData.apo_dist=500; Kuka.MovementData.axis_acc=100; Kuka.MovementData.axis_vel=100; Kuka.MovementData.circ_typ=#BASE; Kuka.MovementData.jerk_fac=50; Kuka.MovementData.ori_typ=#VAR; Kuka.MovementData.vel=2; Kuka.MovementData.acc=100; Kuka.MovementData.exax_ign=0; Kuka.VelocityPath=2; Kuka.BlendingEnabled=False; Kuka.APXEnabled=False; Kuka.CurrentCDSetIndex=0"}
DECL LDAT LCPDAT1 = {CB {AUX_PT {ORI #CONSIDER,E1 #CONSIDER,E2 #CONSIDER,E3 #CONSIDER,E4 #CONSIDER,E5 #CONSIDER,E6 #CONSIDER},TARGET_PT {ORI #INTERPOLATE,E1 #INTERPOLATE,E2 #INTERPOLATE,E3 #INTERPOLATE,E4 #INTERPOLATE,E5 #INTERPOLATE,E6 #INTERPOLATE}},APO_FAC 50.0,APO_DIST 500,AXIS_ACC 100.0,AXIS_VEL 100.0,CIRC_TYP #BASE,JERK_FAC 50.0,ORI_TYP #VAR,VEL 2,ACC 100,GEAR_JERK 100.0,EXAX_IGN 0}
DECL FDAT FMOVE_POS = {BASE_NO 0,TOOL_NO 1,IPO_FRAME #BASE,POINT2[] " "}
ENDDAT
程序关键点说明
1、xml 文件编辑完成后必须放置在C:KRCROBOTERConfigUserCommonEthernetKRL中

并且程序中EKI函数传参时传入的为 xml 文件名。
2、必须声明EKI函数 DECL EKI_STATUS RET

在正确的位置使用相关函数,初始化、连接、发送等
3、使用正确的 GETSET 函数

例如我是需要获取位置变量,那么我直接是使用了GetFrame函数,如果是字符串则是GETSTRING,整数、实数、布尔等同理。
4、如果你是接收或发送的字符串,注意库卡中并没有 String 类型变量,需要使用的字符数组char[],并且字符数组下标从 1 开始。
DECL CHAR TEST_STR[20] 声明了长度为20的字符数组 DECL CHAR TEST_STR1[1] TEST_STR = "ABC" TEST_STR1[1] = TEST_STR[2] 这样赋值到,TEST_STR1[1]值为B
5、合理使用 flag 标志,像我的代码中我只使用了接收到信息的标志,这是不对的,现在代码在创建连接后会直接发送信息,但是可能会出现上位机并未运行等情况,所以需要正确的使用标志位

192.168.0.1 59152
6、更多信息请参阅文档。
python 发送 xml 完成通讯
import socket
import time
# 创建Socket服务器
def start_server():
# 创建一个IPv4 (AF_INET) 和 TCP (SOCK_STREAM) 的socket对象
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定服务器地址和端口
server_address = ('0.0.0.0', 59152)
print(f"启动服务器,监听地址: {server_address[0]}:{server_address[1]}")
server_socket.bind(server_address)
# 监听客户端连接,最大连接数为1
server_socket.listen(1)
print("等待客户端连接...")
# 接受客户端连接
client_socket, client_address = server_socket.accept()
try:
print(f"客户端连接成功: {client_address}")
for i in range(1000):
send_data(client_socket, i + 1, i - 1)
print(client_socket.recv(1024), i)
# time.sleep(3)
send_data(client_socket, 666.666, 666.666)
finally:
# 关闭客户端连接
client_socket.close()
print(f"已断开客户端: {client_address}")
def send_data(socket_client, x, y):
# 定义XML数据
xml_data = f'''
'''
# 发送XML数据到客户端
socket_client.sendall(xml_data.encode('utf-8'))
print(f"已发送数据:
{xml_data}")
# 启动服务器
if __name__ == "__main__":
start_time = time.time()
start_server()
end_time = time.time()
print(f'耗时:{end_time - start_time}')
发送 xml 格式,注意格式,否则无法解析。
测试





这种写法肯定不是最优解,但是在 50 秒内解析并保存完成了 1000 组位置数据,欢迎大佬们有更好的方案一起讨论,不喜勿喷。
全部0条评论
快来发表一下你的评论吧 !