4.Drivers

A robot driver can control a real robot that is connected to a computer. Robot drivers use specific software interfaces to control and monitor a specific robot controller, enabling a computer to directly control a robot arm.

罗依bot drivers provide an alternative to :ref:` Offline Programming ` (where a program is simulated, generated, then, transferred to the robot and executed). With robot drivers you can move a robot while it is being simulated (Online Programming).

The following article shows an example of an Online Programming project using robot drivers://www.sinclairbody.com/blog/online-programming/

Any robot simulation that is programmed in RoboDK can be executed on the robot using a robot driver. The robot movement in the simulator is then synchronized with the real robot and it is possible to debug robot programs in real time.

More information in our documentation://www.sinclairbody.com/doc/en/Robot-Drivers.html#RobotDrivers

4.1.Driver Commands and Responses

罗依boDK communicates to and from the driver using the console or standard input/output. The commands and responses are a list of space-separated arguments in string format. Joint values are in degrees, and follows the number of axis of the robot. Poses use the XYZRPW format (in millimeters/degrees).

List of available commands from RoboDK to the driver:

连接连接请求。RoboDK提供IP、端口and DOF. i.e. CONNECT 192.168.0.100 10000 6 DISCONNECT Disconnect request. i.e. DISCONNECT STOP / QUIT Stop the driver (process terminate). i.e. STOP 192.168.0.100 PAUSE Run a pause. RoboDK provides time in ms. i.e. PAUSE 500 MOVJ Execute a joint move. RoboDK provides joints and pose. i.e. MOVJ -36.3 30.2 -15.3 0.0 75.1 -36.3 156.0 -114.8 187.5 -180.0 0.0 180.0 MOVL Execute a linear move. RoboDK provides joints and pose. i.e. MOVL 18.6 16.8 3.8 0.0 69.3 18.6 156.0 52.7 187.5 -180.0 0.0 180.0 MOVLSEARCH Execute a linear search move. RoboDK provides joints and pose. i.e. MOVLSEARCH 18.6 16.8 3.8 0.0 69.3 18.6 156.0 52.7 187.5 -180.0 0.0 180.0 MOVC Execute a circular move. RoboDK provides joints 1, joints 2, pose 1 and pose 2. i.e. MOVC -4.3 43.0 -36.4 0.0 83.3 -4.3 -36.3 30.2 -15.3 0.0 75.1 -36.3 215.1 -16.3 187.5 -180 0.0 180 156.0 -114.8 187.5 -180 0.0 180 CJNT Request to retrieve the current joint position of the robot. i.e. CJNT SPEED Set the speeds. RoboDK provides mm/s, deg/s, m/s2 and deg/s2. i.e. SPEED 1000.0 200.0 1500.000 150.000 SETROUNDING Set the rounding/smoothing/blending value. Sub-zero values means accurate. i.e. SETROUNDING -1 or SETROUNDING 10 SETDO Set a digital output on the controller. RoboDK provides the IO name and value. i.e. SETDO 5 1 5 1, or SETDO 0 0 VARNAME VALUE WAITDI Wait for a digital input on the controller. RoboDK provides the IO name and value. i.e. WAITDI 5 1 5 1, or WAITDI 0 0 VAR VALUE SETTOOL Set the Tool Center Point. RoboDK provides the pose. i.e. SETTOOL 0.0 0.0 0.0 0.0 0.0 0.0 RUNPROG Run a program call on the controller. RoboDK provides the program ID (if any) and the program name. i.e. RUNPROG 10 Program_10 or RUNPROG -1 ProgramCall POPUP Display a pop-up message on the teach-pendant (if applicable). RoboDK provides the message. i.e. POPUP This is a message

List of available responses from the driver to RoboDK:

SMS Display a message in the connection log window and the connection status bar of RoboDK. The status bar has coloring, for example, "Ready" will be displayed in green, "Waiting" in blue, "Working" in yellow and other messages will be displayed in red. It is recommended to use short, single sentence. e.g. SMS:Ready SMS2 Display a message in the status bar of the main window of RoboDK. e.g. SMS2:Waiting for the controller to warm up RE Report the driver status/response for API Driver command. i.e. "resp = robot.setParam('Driver', some_command)". e.g. RE:OK CMDLIST Display a list of available custom commands in the connection log window of RoboDK. e.g. "CMDLIST:c Command1|This is a command|c Command2|This is a second command|" JNTS Report the robot joints to RoboDK with high accuracy (around 6 decimals). e.g. JNTS:0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000 JNTS_MOVING Report the robot joints to RobDK while the robot is moving (less accurately). e.g. JNTS_MOVING:0.0, 0.0, 0.0, 0.0, 0.0, 0.0

4.2.Driver Example

This section shows a sample Python driver for the KUKA IIWA robot. This driver use TCP/IP to communicate a remote Java server. The example is also available in the /RoboDK/api/Robot/ folder.

apikukaiiwa.py for KUKA IIWA
# -*- coding: UTF-8 -*-# Copyright 2015-2022 - RoboDK Inc. - //www.sinclairbody.com/# Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at# http://www.apache.org/licenses/LICENSE-2.0# Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.##### This is a Python module that allows driving a KUKA IIWA robot.# This Python module can be run directly in console mode to test its functionality.# This module allows communicating with a robot through the command line.# The same commands we can input manually are used by RoboDK to drive the robot from the PC.# RoboDK Drivers are located in /RoboDK/api/Robot/ by default. Drivers can be PY files or EXE files.## Drivers are modular. They are not part of the RoboDK executable but they must be placed in C:/RoboDK/api/robot/, then, linked in the Connection parameters menu:# 1. right click a robot in RoboDK, then, select "Connect to robot".# 2. In the "More options" menu it is possible to update the location and name of the driver.# Driver linking is automatic for currently available drivers.# More information about robot drivers available here:# //www.sinclairbody.com/doc/en/Robot-Drivers.html#RobotDrivers## Alternatively to the standard programming methods (where a program is generated, then, transferred to the robot and executed) it is possible to run a program simulation directly on the robot# The robot movement in the simulator is then synchronized with the real robot.# Programs generated from RoboDK can be run on the robot by right clicking the program, then selecting "Run on robot".# Example:# https://www。youtube.com/watch?v=pCD--kokh4s## Example of an online programming project:# //www.sinclairbody.com/blog/online-programming/## It is possible to control the movement of a robot from the RoboDK API (for example, from a Python or C# program using the RoboDK API).# The same code is used to simulate and optionally move the real robot.# Example:# //www.sinclairbody.com/offline-programming## To establish connection from RoboDK API:# //www.sinclairbody.com/doc/en/PythonAPI/robolink.html#robolink.Item.ConnectSafe## Example of a quick manual test in console mode:# User entry: CONNECT 192.168.123.1 7000#反应:短信:机器人或失败的响应to connect# Response: SMS:Ready# User entry: MOVJ 10 20 30 40 50 60 70# Response: SMS:Working...# Response: SMS:Ready# User entry: CJNT# Response: SMS:Working...# Response: JNTS: 10 20 30 40 50 60 70## ---------------------------------------------------------------------------------importsocketimportstructimportsysimportrefromioimportBytesIO# ---------------------------------------------------------------------------------# Set the minimum number of degrees of freedom that are expectednDOFs_MIN=7# Set the driver versionDRIVER_VERSION="RoboDK Driver for KUKA IIWA v1.0.1"# ---------------------------------------------------------------------------------# KUKA IIWA commandsMSG_CJNT=1MSG_SETTOOL=2MSG_SPEED=3MSG_ROUNDING=4MSG_MOVEJ=10MSG_MOVEL=11MSG_MOVEC=12MSG_MOVEL_SEARCH=13MSG_POPUP=20MSG_PAUSE=21MSG_RUNPROG=22MSG_SETDO=23MSG_WAITDI=24MSG_GETDI=25MSG_SETAO=26MSG_GETAI=27MSG_MONITOR=127MSG_ACKNOWLEDGE=128MSG_DISCONNECT=999# ----------- Communication class for KUKA IIWA robots -------------classComRobot:"""Communication class for KUKA IIWA robots.This class handles communication between this driver (PC) and the robot."""CONNECTED=False# Connection status is known at all times# This is executed when the object is createddef__init__(self):self.BUFFER_SIZE=512# bytesself.TIMEOUT=5*60# seconds: it must be enough time for a movement to completeself.sock=Nonedef__del__(self):self.disconnect()defdisconnect(self):"""Disconnect from the robot."""self.CONNECTED=Falseifself.sock:try:self.sock.close()exceptOSError:returnFalsereturnTruedefconnect(self,ip,port=30000):"""Connect to the robot provided the connection parameters."""globalROBOT_MOVINGself.disconnect()print_message('Connecting to robot%s:%i'%(ip,port))# Create new socket connectionself.sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)self.sock.settimeout(36000)UpdateStatus(ROBOTCOM_WORKING)try:self.sock.connect((ip,port))exceptConnectionRefusedErrorase:print_message(str(e))returnFalseself.CONNECTED=TrueROBOT_MOVING=Falseself.send_line(DRIVER_VERSION)print_message('Waiting for welcome message...')robot_response=self.recv_line()print(robot_response)sys.stdout.冲洗()returnTruedefsend_b(self,msg):"""Send a line to the robot through the communication port (TCP/IP)."""try:sent=self.sock.send(msg)ifsent==0:returnFalsereturnTrueexceptConnectionAbortedErrorase:self.CONNECTED=Falseprint(str(e))returnFalsedefrecv_b(self,buffer_size):”“”获得line from the robot through the communication port (TCP/IP)."""bytes_io=BytesIO()try:foriinrange(buffer_size):bytes_io.write(self.sock.recv(1))b_data=bytes_io.getvalue()exceptConnectionAbortedErrorase:self.CONNECTED=Falseprint(str(e))returnNoneifb_data==b'':returnNonereturnb_datadefsend_line(self,string=None):"""Sends a string of characters with a \\n to the robot."""string=string.replace('\n','
'
)ifsys.version_info[0]<3:returnself.send_b(bytes(string+'\0'))# Python 2.x onlyelse:returnself.send_b(bytes(string+'\0','utf-8'))# Python 3.x onlydefrecv_line(self):"""Receives a string from the robot. It reads until a null terminated string"""string=b''chari=self.recv_b(1)whilechari!=b'\0':# read until null terminatedstring=string+charichari=self.recv_b(1)returnstr(string.decode('utf-8'))# python 2 and python 3 compatibledefsend_int(self,num):"""Sends an int (32 bits) to the robot."""ifisinstance(num,float):num=round(num)elifnotisinstance(num,int):num=num[0]returnself.send_b(struct.pack('>i',num))defrecv_int(self):"""Receives an int (32 bits) from the robot."""buffer=self.recv_b(4)num=struct.unpack('>i',buffer)returnnum[0]defrecv_double(self):"""Receives an double (64 bits) from the robot."""buffer=self.recv_b(8)num=struct.unpack('>d',buffer)returnnum[0]defrecv_acknowledge(self):"""Wait to receives a command acknowledge from the robot."""whileTrue:stat_ack=self.recv_int()ifstat_ack==MSG_MONITOR:jnts_moving=self.recv_array()print_joints(jnts_moving,True)elifstat_ack==MSG_ACKNOWLEDGE:returnTrueelse:print_message("Unexpected response from the robot")UpdateStatus(ROBOTCOM_CONNECTION_PROBLEMS)self.disconnect()returnFalsedefsend_array(self,values):"""Sends an array of doubles to the robot."""ifnotisinstance(values,list):# if it is a Mat() with jointsvalues=(values.tr()).rows[0]n_values=len(values)ifnotself.send_int(n_values):returnFalseifn_values>0:buffer=b''foriinrange(n_values):buffer=buffer+struct.pack('>d',values[i])returnself.send_b(buffer)returnTruedefrecv_array(self):"""Receives an array of doubles from the robot."""n_values=self.recv_int()# print_message('n_values: %i' % n_values)values=[]ifn_values>0:buffer=self.recv_b(8*n_values)values=list(struct.unpack('>'+str(n_values)+'d',buffer))# print('values: ' + str(values))returnvaluesdefSendCmd(self,cmd,values=None):"""Send a command to the robot. Returns True if success, False otherwise."""# print('SendCmd(cmd=' + str(cmd) + ', values=' + str(values) if values else '' + ')')# Skip the command if the robot is not connectedifnotself.CONNECTED:UpdateStatus(ROBOTCOM_NOT_CONNECTED)returnFalseifnotself.send_int(cmd):print_message("Robot connection broken")UpdateStatus(ROBOTCOM_NOT_CONNECTED)returnFalseifvaluesisNone:returnTrueelifnotisinstance(values,list):values=[values]ifnotself.send_array(values):print_message("Robot connection broken")UpdateStatus(ROBOTCOM_NOT_CONNECTED)returnFalsereturnTrue# -----------------------------------------------------------------------------# -----------------------------------------------------------------------------# Generic RoboDK driver for a specific Robot classROBOT=ComRobot()ROBOT_IP="172.31.1.147"# IP of the robotROBOT_PORT=30000# Communication port of the robotROBOT_MOVING=False# ------------ Robot connection -----------------# Establish connection with the robotdef罗依botConnect():globalROBOTglobalROBOT_IPglobalROBOT_PORTreturnROBOT.connect(ROBOT_IP,ROBOT_PORT)# Disconnect from the robotdef罗依botDisconnect():globalROBOTROBOT.disconnect()returnTrue# -----------------------------------------------------------------------------# Generic RoboDK driver tools# Note, a simple print() will flush information to the log window of the robot connection in RoboDK# Sending a print() might not flush the standard output unless the buffer reaches a certain sizedefprint_message(message):"""Display a message in the connection log window and the connection status bar of RoboDK (SMS:).The status bar has coloring, for example, \"Ready\" will be displayed in green, \"Waiting\" in blue, \"Working\" in yellow and other messages will be displayed in red.It is recommended to use short, single sentence."""print("SMS:"+message)sys.stdout.冲洗()# very useful to update RoboDK as fast as possibledefshow_message(message):"""Display a message in the status bar of the main window of RoboDK (SMS2:)."""print("SMS2:"+message)sys.stdout.冲洗()# very useful to update RoboDK as fast as possibledefprint_response(message):"""Report the driver status/response for API Driver command (RE:).i.e. \"resp = robot.setParam('Driver', some_command)\"."""print("RE:"+message)sys.stdout.冲洗()# very useful to update RoboDK as fast as possibledefprint_commands(message):"""Display a list of available custom commands (c) in the connection log window of RoboDK (CMDLIST:).e.g. \"c Command1|This is a command|c Command2|This is a second command|\""""print("CMDLIST:"+message)sys.stdout.冲洗()# very useful to update RoboDK as fast as possibledefprint_joints(joints,is_moving=False):"""Report the robot joints to RoboDK (JNTS: or JNTS_MOVING:).Provide accurate joint values when the robot is static (JNTS:), or less precision if the robot is currently moving (JNTS_MOVING:)."""ifis_moving:# Display the feedback of the joints when the robot is movingifROBOT_MOVING:print("JNTS_MOVING: "+" ".join(format(x,".3f")forxinjoints))else:print("JNTS: "+" ".join(format(x,".6f")forxinjoints))sys.stdout.冲洗()# very useful to update RoboDK as fast as possible# ---------------------------------------------------------------------------------# Constant values to display status using UpdateStatus()ROBOTCOM_UNKNOWN=-1000#:未知状态(红色)ROBOTCOM_CONNECTION_PROBLEMS=-3#: Robot connection problems status (red)ROBOTCOM_DISCONNECTED=-2#: Robot disconnected status (red)ROBOTCOM_NOT_CONNECTED=-1#: Robot not connected status (red)ROBOTCOM_READY=0#: Robot ready status (green), i.e. SMS:ReadyROBOTCOM_WORKING=1#: Robot working status (yellow), i.e. SMS:WorkingROBOTCOM_WAITING=2#: Waiting on robot status (blue), i.e. SMS:Waiting# Last robot status is savedSTATUS=ROBOTCOM_DISCONNECTEDdefUpdateStatus(set_status=None):"""UpdateStatus will send an appropriate message to RoboDK which will result in a specific coloring.For example, \"Ready\" will be displayed in green, \"Waiting\" in blue, \"Working\" in yellowand other messages will be displayed in red.e.g. SMS:Ready"""globalSTATUSifset_statusisnotNone:STATUS=set_statusifSTATUS==ROBOTCOM_CONNECTION_PROBLEMS:print_message("Connection problems")elifSTATUS==ROBOTCOM_DISCONNECTED:print_message("Disconnected")elifSTATUS==ROBOTCOM_NOT_CONNECTED:print_message("Not connected")elifSTATUS==ROBOTCOM_READY:print_message("Ready")elifSTATUS==ROBOTCOM_WORKING:print_message("Working...")elifSTATUS==ROBOTCOM_WAITING:print_message("Waiting...")else:print_message("Unknown status")# Sample set of commands that can be provided by RoboDK of through the command linedefTestDriver():RunCommand("CONNECT")RunCommand("SPEED 250")RunCommand("SETTOOL -0.025 -41.046 50.920 60.000 -0.000 90.000")RunCommand("CJNT")RunCommand("MOVJ -5.362010 46.323420 20.746290 74.878840 -50.101680 61.958500")RunCommand("MOVEL 0 0 0 0 0 0 -5.362010 50.323420 20.746290 74.878840 -50.101680 61.958500")RunCommand("PAUSE 1000")RunCommand("DISCONNECT")# -------------------------- Main driver loop -----------------------------# Read STDIN and process each command (infinite loop)# IMPORTANT: This must be run from RoboDK so that RoboDK can properly feed commands through STDIN# This driver can also be run in console mode providing the commands through the console inputdefRunDriver():"""Main driver loop. Reads STDIN and process each command (infinite loop)."""forlineinsys.stdin:RunCommand(line)defRunCommand(cmd_line):"""Parse a RoboDK command string (STDIN or command line) and forward the appropriate action to the robot communication class.Command strings are prefixed with a command, followed by its arguments (space-separated).Joint values are in degrees, and follows the number of axis of the robot.Poses use the XYZRPW format (in millimeters/degrees).:param str cmd_line: The command stringAvailable commands:.. code-block:: text连接连接请求。RoboDK提供IP、端口and DOF.i.e. CONNECT 192.168.0.100 10000 6DISCONNECT Disconnect request.i.e. DISCONNECTSTOP / QUIT Stop the driver (process terminate).i.e. STOP 192.168.0.100PAUSE Run a pause. RoboDK provides time in ms.i.e. PAUSE 500MOVJ Execute a joint move. RoboDK provides joints and pose.i.e. MOVJ -36.3 30.2 -15.3 0.0 75.1 -36.3 156.0 -114.8 187.5 -180.0 0.0 180.0MOVL Execute a linear move. RoboDK provides joints and pose.i.e. MOVL 18.6 16.8 3.8 0.0 69.3 18.6 156.0 52.7 187.5 -180.0 0.0 180.0MOVLSEARCH Execute a linear search move. RoboDK provides joints and pose.i.e. MOVLSEARCH 18.6 16.8 3.8 0.0 69.3 18.6 156.0 52.7 187.5 -180.0 0.0 180.0MOVC Execute a circular move. RoboDK provides joints 1, joints 2, pose 1 and pose 2.i.e. MOVC -4.3 43.0 -36.4 0.0 83.3 -4.3 -36.3 30.2 -15.3 0.0 75.1 -36.3 215.1 -16.3 187.5 -180 0.0 180 156.0 -114.8 187.5 -180 0.0 180CJNT Request to retrieve the current joint position of the robot.i.e. CJNTSPEED Set the speeds. RoboDK provides mm/s, deg/s, m/s2 and deg/s2.i.e. SPEED 1000.0 200.0 1500.000 150.000SETROUNDING Set the rounding/smoothing/blending value. Sub-zero values means accurate.i.e. SETROUNDING -1 or SETROUNDING 10SETDO Set a digital output on the controller. RoboDK provides the IO name and value.i.e. SETDO 5 1 5 1, or SETDO 0 0 VARNAME VALUEWAITDI Wait for a digital input on the controller. RoboDK provides the IO name and value.i.e. WAITDI 5 1 5 1, or WAITDI 0 0 VAR VALUESETTOOL Set the Tool Center Point. RoboDK provides the pose.i.e. SETTOOL 0.0 0.0 0.0 0.0 0.0 0.0RUNPROG Run a program call on the controller. RoboDK provides the program ID (if any) and the program name.i.e. RUNPROG 10 Program_10 or RUNPROG -1 ProgramCallPOPUP Display a pop-up message on the teach-pendant (if applicable). RoboDK provides the message.i.e. POPUP This is a message"""ifcmd_line.strip()=="":# Skip if no command is providedreturnglobalROBOT_IPglobalROBOT_PORTglobalROBOTglobalROBOT_MOVING# strip a line of words into a list of numbersdefline_2_values(line):values=[]forwordinline:try:number=float(word)values.append(number)exceptValueError:passreturnvaluescmd_words=cmd_line.split(' ')# [''] if len == 0cmd=cmd_words[0]cmd_values=line_2_values(cmd_words[1:])# [] if len <= 1n_cmd_values=len(cmd_values)n_cmd_words=len(cmd_words)received=Noneifcmd_line.startswith("CONNECT"):# Connect to robot provided the IP and the portifn_cmd_words>=2:ROBOT_IP=cmd_words[1]ifn_cmd_words>=3:ROBOT_PORT=int(cmd_words[2])received=罗依botConnect()elifn_cmd_values>=nDOFs_MINandcmd_line.startswith("MOVJ"):UpdateStatus(ROBOTCOM_WORKING)#激活监控反馈ROBOT_MOVING=True# Execute a joint move. RoboDK provides j1,j2,...,j6,j7,x,y,z,w,p,rifROBOT.SendCmd(MSG_MOVEJ,cmd_values):# Wait for command to be executedifROBOT.recv_acknowledge():# Notify that we are done with this commandUpdateStatus(ROBOTCOM_READY)elifn_cmd_values>=nDOFs_MINandcmd_line.startswith("MOVLSEARCH"):UpdateStatus(ROBOTCOM_WORKING)#激活监控反馈ROBOT_MOVING=True# Execute a linear move. RoboDK provides j1,j2,...,j6,x,y,z,w,p,rifROBOT.SendCmd(MSG_MOVEL_SEARCH,cmd_values[0:n_cmd_values]):# Wait for command to be executedifROBOT.recv_acknowledge():# Retrieve contact jointsjnts_contact=ROBOT.recv_array()print_joints(jnts_contact)elifn_cmd_values>=nDOFs_MINandcmd_line.startswith("MOVL"):UpdateStatus(ROBOTCOM_WORKING)#激活监控反馈ROBOT_MOVING=True# Execute a linear move. RoboDK provides j1,j2,...,j6,j7,x,y,z,w,p,rifROBOT.SendCmd(MSG_MOVEL,cmd_values):# Wait for command to be executedifROBOT.recv_acknowledge():# Notify that we are done with this commandUpdateStatus(ROBOTCOM_READY)elifn_cmd_values>=2*(nDOFs_MIN+6)andcmd_line.startswith("MOVC"):UpdateStatus(ROBOTCOM_WORKING)#激活监控反馈ROBOT_MOVING=True# Execute a circular move. RoboDK provides j1,j2,...,j6,x,y,z,w,p,r for two targetsxyzwpr12=cmd_values[-12:]ifROBOT.SendCmd(MSG_MOVEC,xyzwpr12):# Wait for command to be executedifROBOT.recv_acknowledge():# Notify that we are done with this commandUpdateStatus(ROBOTCOM_READY)elifcmd_line.startswith("CJNT"):UpdateStatus(ROBOTCOM_WORKING)# Retrieve the current position of the robotifROBOT.SendCmd(MSG_CJNT):received=ROBOT.recv_array()print_joints(received)elifn_cmd_values>=1andcmd_line.startswith("SPEED"):UpdateStatus(ROBOTCOM_WORKING)# First value is linear speed in mm/s# IMPORTANT! We should only send one "Ready" per instructionspeed_values=[-1,-1,-1,-1]foriinrange(max(4,len(cmd_values))):speed_values[i]=cmd_values[i]# speed_values[0] = speed_values[0] # linear speed in mm/s# speed_values[1] = speed_values[1] # joint speed in mm/s# speed_values[2] = speed_values[2] # linear acceleration in mm/s2# speed_values[3] = speed_values[3] # joint acceleration in deg/s2ifROBOT.SendCmd(MSG_SPEED,speed_values):# Wait for command to be executedifROBOT.recv_acknowledge():# Notify that we are done with this commandUpdateStatus(ROBOTCOM_READY)elifn_cmd_values>=6andcmd_line.startswith("SETTOOL"):UpdateStatus(ROBOTCOM_WORKING)# Set the Tool reference frame provided the 6 XYZWPR cmd_values by RoboDKifROBOT.SendCmd(MSG_SETTOOL,cmd_values):# Wait for command to be executedifROBOT.recv_acknowledge():# Notify that we are done with this commandUpdateStatus(ROBOTCOM_READY)elifn_cmd_values>=1andcmd_line.startswith("PAUSE"):UpdateStatus(ROBOTCOM_WAITING)# Run a pauseifROBOT.SendCmd(MSG_PAUSE,cmd_values[0]):# Wait for command to be executedifROBOT.recv_acknowledge():# Notify that we are done with this commandUpdateStatus(ROBOTCOM_READY)elifn_cmd_values>=1andcmd_line.startswith("SETROUNDING"):# Set the rounding/smoothing value. Also known as ZoneData in ABB or CNT for FanucifROBOT.SendCmd(MSG_ROUNDING,cmd_values[0]):# Wait for command to be executedifROBOT.recv_acknowledge():# Notify that we are done with this commandUpdateStatus(ROBOTCOM_READY)elifn_cmd_values>=2andcmd_line.startswith("SETDO"):UpdateStatus(ROBOTCOM_WORKING)# dIO_id = cmd_values[0]# dIO_value = cmd_values[1]ifROBOT.SendCmd(MSG_SETDO,cmd_values[0:2]):# Wait for command to be executedifROBOT.recv_acknowledge():# Notify that we are done with this commandUpdateStatus(ROBOTCOM_READY)elifn_cmd_values>=2andcmd_line.startswith("WAITDI"):UpdateStatus(ROBOTCOM_WORKING)# dIO_id = cmd_values[0]# dIO_value = cmd_values[1]ifROBOT.SendCmd(MSG_WAITDI,cmd_values[0:2]):# Wait for command to be executedifROBOT.recv_acknowledge():# Notify that we are done with this commandUpdateStatus(ROBOTCOM_READY)elifn_cmd_values>=1andn_cmd_words>=3andcmd_line.startswith("RUNPROG"):UpdateStatus(ROBOTCOM_WORKING)program_id=cmd_values[0]# Program ID is extracted automatically if the program name is Program IDcode=cmd_words[2]# "Program%i" % program_idm=re.search(r'^(?P.*)\((?P.*)\)',code)code_dict=m.groupdict()program_name=code_dict['program_name']args=code_dict['args'].replace(' ','').split(',')print('program_name: '+program_name)print('args: '+str(args))ROBOT.SendCmd(MSG_RUNPROG)ROBOT.send_int(program_id)ROBOT.send_line(program_name)forainargs:ROBOT.send_line(a)# Wait for the program call to completeifROBOT.recv_acknowledge():# Notify that we are done with this commandUpdateStatus(ROBOTCOM_READY)elifn_cmd_words>=2andcmd_line.startswith("POPUP "):UpdateStatus(ROBOTCOM_WORKING)message=cmd_line[6:]ROBOT.send_line(message)# Wait for command to be executedifROBOT.recv_acknowledge():# Notify that we are done with this commandUpdateStatus(ROBOTCOM_READY)elifcmd_line.startswith("DISCONNECT"):# Disconnect from robotROBOT.SendCmd(MSG_DISCONNECT)ROBOT.recv_acknowledge()ROBOT.disconnect()UpdateStatus(ROBOTCOM_DISCONNECTED)elifcmd_line.startswith("STOP")orcmd_line.startswith("QUIT"):# Stop the driverçROBOT.SendCmd(MSG_DISCONNECT)ROBOT.disconnect()UpdateStatus(ROBOTCOM_DISCONNECTED)quit(0)# Stop the driverelifcmd_line.startswith("c "):# Custom commands that are forwarded as-ispasselifcmd_line=="t":# Call custom procedure for quick testingTestDriver()else:print("Unknown command: "+str(cmd_line))ifreceivedisnotNone:UpdateStatus(ROBOTCOM_READY)# Stop monitoring feedbackROBOT_MOVING=FalsedefRunMain():调用主程序”“”“#冲洗版本print_message("RoboDK Driver v2.0 for KUKA IIWA robot controllers")# It is important to disconnect the robot if we force to stop the processimportatexitatexit.register(罗依botDisconnect)# Flush Disconnected messageprint_message(DRIVER_VERSION)UpdateStatus()# Run the driver from STDINRunDriver()# Test the driver with a sample set of commandsTestDriver()if__name__=="__main__":调用主程序”“”“# Important, leave the Main procedure as RunMainRunMain()