├── README.md ├── VC4.0 ├── Robot_Cell_MTP.vcmx └── Robot_Cell_MTP_case.vcmx ├── gui ├── opcua-server-gui.py ├── server_gui_VC4_0.py ├── server_gui_motorCurrent.py ├── server_gui_motorSpeed.py ├── server_gui_motorTemperature.py ├── server_gui_motorTorque.py ├── server_gui_write_motorCurrent.py ├── server_gui_write_motorSpeed.py ├── server_gui_write_motorTemperature.py └── server_gui_write_motorTorque.py ├── opcua-control ├── opcua-control-server.py ├── opcua_ptp_movement.dat └── opcua_ptp_movement.src ├── opcua-server ├── opcua-server-current-to-file.py ├── opcua-server-current.py ├── opcua-server-temperature-to-file.py ├── opcua-server-temperature.py ├── opcua-server-torque-to-file.py ├── opcua-server-torque.py ├── opcua-server-velocity-to-file.py ├── opcua-server-velocity.py ├── opcua-server01.py └── opcua-server02.py ├── pictures ├── Connected_Variables_VC_4.0.png ├── InformationFlow.png ├── Physical_&_digital_model.png ├── VCmodel.png └── gui_full.png ├── rsi ├── RSIAxisCorrTestConfig2016v2.xml ├── RSI_AxisCorr2016v2.src └── rsi-opcua-server.py └── xml ├── KUKAVARPROXY_communication.py ├── KUKA_KR120_object.xml ├── KUKA_KR16_2_object.xml ├── KUKA_KR5_object.xml └── opcua-server-xml.py /README.md: -------------------------------------------------------------------------------- 1 | # Digital Twin with OPC UA 2 | This repository contains files used in the development of a digital twin (DTw) for a robot cell at NTNU with the use of Visual Components 4.0 (VC 4.0) and OPC UA. 3 | 4 | **Master's Thesis:** http://hdl.handle.net/11250/2561319 5 | 6 | **Grade:** A 7 | 8 | ## Result 9 | The system currently contains the following functionality: 10 | 1. Programming, planning and control in VC 4.0 11 | 2. Mirror movements of physical robot cell in real-time using KUKAVARPROXY (KVP),
12 | average read time 8.75ms 13 | 3. Mirror movements of physical robot cell in real-time using RSI,
14 | average read time 4.00ms 15 | 4. Plot sensor data for every KUKA robot: 16 | * Velocity of the motors controlling all axes 17 | * Torque on the motors controlling all axes 18 | * Current to the motors controlling all axes 19 | * Temperature of the motors controlling all axes 20 | 5. Write sensor data for every KUKA robot to .csv files: 21 | * Velocity to file 22 | * Torque to file 23 | * Current to file 24 | * Temperature to file 25 | 6. GUI for access to functionalities 26 | 7. Extraction of physical robot properties through XML 27 | 8. Controlling physical robots from VC 4.0 using KVP 28 | 29 | It was done a fixed case with camera tracking to illustrate some of the functionalities of the DTw:
30 | https://youtu.be/xlQhQPmJwlA 31 | 32 | ## Needs improvement 33 | - [ ] MDA approach to OPC UA information model design 34 | - [ ] Avoid middleware between PC running VC 4.0 and KR C4 robot controllers 35 | - [ ] Remove lag in control of robots through VC 4.0 using KVP 36 | - [ ] Development of an OPC UA server controlling robots through VC 4.0, using RSI 37 | - [ ] Move plotting of data, and camera stream, from middleware to VC 4.0 38 | - [ ] Develop a more accurate calibrated model of the robot cell 39 | - [ ] Gather all functionalities in one server 40 | - [ ] Add sharing of sensor data to online databases 41 | 42 | For more information about improvements, see the project report section 5.1.2:
43 | http://hdl.handle.net/11250/2561319 44 | 45 | --- 46 | 47 | ## About Project 48 | This project was initiated by the Norwegian University of Science and Technology (NTNU), Department of Production Technology. The aim of the project was the following: 49 | 50 | In order to respond quickly to unexpected events and new demands without extensive system changes, future production systems must be able to work more independently. There is a need for intelligent machines that perform complex tasks without detailed programming and without human interaction. Autonomous systems know their own abilities (which are modeled as "skills") and their state. They are able to choose between a set of possible actions, orchestrating and perform their skills. To succeed, the autonomous systems need to have realistic models of the current state of the production process and the system's own behaviour in interaction with its external environment - usually called a digital twin. 51 | 52 | OPC Unified Architecture (OPC UA) is a platform-independent protocol for machine-to-machine communication for industrial automation developed by the OPC Foundation. OPC focuses on accessing large amounts of real-time data at the same time as system performance is affected to a minimum. OPC UA has the potential to become an important foundation in the future industrial environment where machines deliver "production as a service", and all machines and sensors in production are online (Internet of Things). 53 | 54 | In this task, implementation of a digital twin will be studied. A solution must be developed that provides seamless communication between robots, PLSs, and other relevant control systems that can be part of an industrial production system, linked to one digital representation of the system. The system must be tested at the institute Robot Laboratory. 55 | 56 | **a)** Describe how a digital twin can be implemented using OPC UA. 57 | 58 | **b)** Examine the advantages and disadvantages of using Visual Components 4.0 or similar simulation software
59 | for the digital twin. 60 | 61 | **c)** Use Visual Components 4.0 or similar simulation software to model and simulate the robot cell at the Institute. 62 | 63 | **d)** Examine the advantages and disadvantages of using KUKAVARPROXY and KUKA RSI Ethernet as middleware
64 | between the KUKA KR C4 robot controllers and the digital twin. 65 | 66 | **e)** Present a solution for a digital twin of the Institute's Robot Laboratory with use of OPC UA for communication. 67 | 68 | **f)** Try out the system in a fixed case. Evaluate the results. 69 | 70 | ## Abstract 71 | This project explores the term Industry 4.0 (I 4.0) and the use of Digital Twins (DTws) as an asset in this modern industrial revolution. A DTw can be described as a digital replica of a physical system including data about this systems interaction with its environment. The goal of this project has been to develop a DTw for a robot cell at MTP Valgrinda, NTNU, and investigate what benefits could be gained from introducing the technology in this system and the domain of automated robotic systems in general. 72 | 73 | The DTw was developed using the OPC UA communication architecture. OPC UA is called the pioneer of I 4.0 as it is a communication architecture aiming at the standardization of communication in industry. Three different visualization software solutions were compared. It was concluded that Visual Components 4.0 (VC 4.0) was the strongest candidate for developing a visual representation of the robot cell. Using VC 4.0 and OPC UA a DTw of the robot cell was created. 74 | 75 | Most of the work done in this project revolved around creating communication modules able to connect the physical robot cell to the virtual representation in VC 4.0, through the use of OPC UA. The result of this work is a communication library containing the virtual representation of the robot cell and the different communication modules able to give the DTw various functionalities. This library is made open-source and can be found in the project's GitHub repository at 76 | 77 | https://github.com/akselov/digital-twin-opcua 78 | 79 | The software included in this library enables the DTw to do real-time mirroring of the physical robot's movements, plotting of robotic sensor data and controlling the robots from the DTw. A graphical user interface was developed to organize the functionalities. Figure 2 illustrates the current communication architecture for the DTw. 80 | 81 | The DTw was tested in a fixed case. This was a multi-robot case including mirroring of movements, plotting of sensor data and control from VC 4.0. It was made a video from the case which is published online at 82 | 83 | https://youtu.be/xlQhQPmJwlA 84 | 85 | It was concluded that OPC UA was a good solution for use in this DTw as it is possible to implement on any platform, and is enabling a more flexible and structured way of communicating than traditional communication software used in client/server based systems. The benefits found with the use of the DTw in this automated robotic system included visibility to operations and a better foundation for statistical analysis to predict future states and for optimizing characteristic parameters associated with the robot cell. Finally, it was concluded that the DTw act as a good foundation for managing a complex system, something that could be beneficial as this specific system is used in training and professional development at the institute. 86 | 87 | ![Figure 1](https://github.com/akselov/digital-twin-opcua/blob/master/pictures/Physical_%26_digital_model.png) 88 |
**Figure 1: Robot cell, physical and digital** 89 | 90 | 91 | ![Figure 2](https://github.com/akselov/digital-twin-opcua/blob/master/pictures/InformationFlow.png) 92 | **Figure 2: Current communication architecture** 93 | 94 | 95 | ## Python GUI 96 | GUI for launching Visual Components 4.0 OPC UA connection, displaying robot sensor data and writing data to .csv files. 97 | 98 | ![Figure 3](https://github.com/akselov/digital-twin-opcua/blob/master/pictures/gui_full.png) 99 | **Figure 3: GUI** 100 | 101 | ## Visual Components 4.0 102 | This library contains two files of the robot cell from VC 4.0: 103 | 1. *Robot_Cell_MTP.vcmx*, Version compatible with all servers developed,
104 | including one example OPC UA client set up for controlling the KUKA KR 16-2 from VC 4.0 105 | 2. *Robot_Cell_MTP_case.vcmx*, Version used in the fixed case, including two OPC UA clients set up.
106 | One for controlling the KUKA KR 120 R2500 from VC 4.0, and one for extracting the axis variables
107 | from the KUKA KR 16-2 and mirror its movements in VC 4.0. 108 | 109 | ![Figure 4](https://github.com/akselov/digital-twin-opcua/blob/master/pictures/VCmodel.png) 110 | **Figure 4: Screenshot from VC 4.0** 111 | 112 | ## Acknowledgments 113 | The software developed in this project is based on work by: 114 | - Massimiliano Fago (https://sourceforge.net/projects/openshowvar) 115 | - Mechatronics Lab at AAlesund University College (https://github.com/aauc-mechlab/JOpenShowVar) 116 | - Ahmad Saeed (https://github.com/akselov/kukavarproxy-msg-format) 117 | - Olivier Roulet-Dubonnet (https://github.com/FreeOpcUa) 118 | - Torstein Anderssen Myhre (https://github.com/torstem/examplecode-kukarsi-python) 119 | -------------------------------------------------------------------------------- /VC4.0/Robot_Cell_MTP.vcmx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akselov/digital-twin-opcua/adc30f46466595a278f87f23a304a3630deca4da/VC4.0/Robot_Cell_MTP.vcmx -------------------------------------------------------------------------------- /VC4.0/Robot_Cell_MTP_case.vcmx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akselov/digital-twin-opcua/adc30f46466595a278f87f23a304a3630deca4da/VC4.0/Robot_Cell_MTP_case.vcmx -------------------------------------------------------------------------------- /gui/opcua-server-gui.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Source code for a GUI able to execute different OPC UA servers 3 | with a variety of functionalities for a KUKA robot: 4 | - Send axis parameters to Visual Components 4.0 5 | - Display sensor data of motors controlling each axis 6 | (real-time plotting): 7 | # Motor velocity 8 | # Motor torque 9 | # Motor current 10 | # Motor temperature 11 | - Write sensor data to .csv files 12 | 13 | Author: Aksel Oevern 14 | NTNU 2018 15 | ''' 16 | 17 | import tkinter as tk 18 | from tkinter import ttk 19 | from tkinter import messagebox 20 | from tkinter import * 21 | LARGE_FONT= ("Verdana", 12) 22 | import sys 23 | import subprocess 24 | 25 | # Setup KUKA Monitiong Application GUI 26 | class KUKA_APP(tk.Tk): 27 | 28 | def __init__(self, *args, **kwargs): 29 | tk.Tk.__init__(self, *args, **kwargs) 30 | tk.Tk.iconbitmap(self, "robot-16.ico") 31 | tk.Tk.wm_title(self, "KUKA KR 16-2 Monitoring Application") 32 | tk.Tk.geometry(self,'400x260') 33 | 34 | container = tk.Frame(self) 35 | container.pack(side="top", fill="both", expand = True) 36 | container.grid_rowconfigure(0, weight=1) 37 | container.grid_columnconfigure(0, weight=1) 38 | 39 | canvas = Canvas(self, width=2000, height=2000) 40 | canvas.place(x = -100, y = 220) 41 | blackLine = canvas.create_line(0,2,2000,2) 42 | canvas.configure(background='gray') 43 | 44 | canvas_id = canvas.create_text(432,25) 45 | canvas.itemconfig(canvas_id, text = "akselov@stud.ntnu.no") 46 | canvas.insert(canvas_id, 12, "") 47 | 48 | self.frames = {} 49 | 50 | for F in (StartPage, PageOne, PageTwo, PageThree): 51 | frame = F(container, self) 52 | self.frames[F] = frame 53 | frame.grid(row=0, column=0, sticky="nsew") 54 | 55 | self.show_frame(StartPage) 56 | 57 | def show_frame(self, cont): 58 | frame = self.frames[cont] 59 | frame.tkraise() 60 | 61 | class StartPage(tk.Frame): 62 | def __init__(self, parent, controller): 63 | tk.Frame.__init__(self,parent) 64 | label = tk.Label(self, text="KUKA KR 16-2 Monitoring Application", font=LARGE_FONT) 65 | label.place(x=44,y=10) 66 | 67 | button1 = ttk.Button(self, text="Send axis parameters to Visual Components 4.0", 68 | command=lambda: controller.show_frame(PageOne)) 69 | button1.place(x=65,y=50) 70 | 71 | button2 = ttk.Button(self, text="Display sensor data", 72 | command=lambda: controller.show_frame(PageThree)) 73 | button2.place(x=65,y=80) 74 | 75 | button3 = ttk.Button(self, text="Write data to file", 76 | command=lambda: controller.show_frame(PageTwo)) 77 | button3.place(x=65,y=110) 78 | 79 | close_button = ttk.Button(self, text="Close",command=self.quit) 80 | 81 | close_button.place(x=65,y=140) 82 | 83 | class PageOne(tk.Frame): 84 | def __init__(self, parent, controller): 85 | tk.Frame.__init__(self, parent) 86 | label = tk.Label(self, text="Axis parameters to Visual Components 4.0", font=LARGE_FONT) 87 | label.place(x=20,y=10) 88 | 89 | button1 = ttk.Button(self, text="Back to Home", 90 | command=lambda: controller.show_frame(StartPage)) 91 | button1.place(x=65,y=50) 92 | 93 | button2 = ttk.Button(self, text="Start connection", 94 | command= send_axis_parameters) 95 | button2.place(x=65,y=80) 96 | 97 | class PageTwo(tk.Frame): 98 | def __init__(self, parent, controller): 99 | tk.Frame.__init__(self, parent) 100 | label = tk.Label(self, text="Write data to file", font=LARGE_FONT) 101 | label.place(x=120,y=10) 102 | 103 | button1 = ttk.Button(self, text="Back to home", 104 | command=lambda: controller.show_frame(StartPage)) 105 | button1.place(x=65,y=50) 106 | 107 | button2 = ttk.Button(self, text="Write Motor Speed to file", 108 | command = write_motorSpeed_to_file) 109 | button2.place(x=65,y=80) 110 | 111 | button3 = ttk.Button(self, text="Write Motor Torque to file", 112 | command = write_motorTorque_to_file) 113 | button3.place(x=65,y=110) 114 | 115 | button4 = ttk.Button(self, text="Write Motor Current to file", 116 | command = write_motorCurrent_to_file) 117 | button4.place(x=65,y=140) 118 | 119 | button5 = ttk.Button(self, text="Write Motor Temperature to file", 120 | command = write_motorTemp_to_file) 121 | button5.place(x=65,y=170) 122 | 123 | class PageThree(tk.Frame): 124 | def __init__(self, parent, controller): 125 | tk.Frame.__init__(self, parent) 126 | label = tk.Label(self, text="Display sensor data", font=LARGE_FONT) 127 | label.place(x=110,y=10) 128 | 129 | button0 = ttk.Button(self, text="Back to Home", 130 | command=lambda: controller.show_frame(StartPage)) 131 | button0.place(x=65,y=50) 132 | 133 | button1 = ttk.Button(self, text="Display Motor Speed monitor", 134 | command= motor_speed_monitor) 135 | button1.place(x=65,y=80) 136 | 137 | button2 = ttk.Button(self, text="Display Motor Torque monitor", 138 | command= motor_torque_monitor) 139 | button2.place(x=65,y=110) 140 | 141 | button3 = ttk.Button(self, text="Display Motor Current monitor", 142 | command= motor_current_monitor) 143 | button3.place(x=65,y=140) 144 | 145 | button4 = ttk.Button(self, text="Display Motor Temperature monitor", 146 | command= motor_temp_monitor) 147 | button4.place(x=65,y=170) 148 | 149 | def send_axis_parameters(): 150 | messagebox.showinfo("Monitor axis parameters", "Axis parameters will now be available in Visual Components 4.0") 151 | subprocess.call([sys.executable, 'server_gui_VC4_0.py', 'argument1', 'argument2']) 152 | 153 | def motor_speed_monitor(): 154 | messagebox.showinfo("Display sensor data", "Motor Speed data will be displayed in a new window") 155 | subprocess.call([sys.executable, 'server_gui_motorSpeed.py', 'argument1', 'argument2']) 156 | 157 | def motor_torque_monitor(): 158 | messagebox.showinfo("Display sensor data", "Motor Torque data will be displayed in a new window") 159 | subprocess.call([sys.executable, 'server_gui_motorTorque.py', 'argument1', 'argument2']) 160 | 161 | def motor_current_monitor(): 162 | messagebox.showinfo("Display sensor data", "Motor Current data will be displayed in a new window") 163 | subprocess.call([sys.executable, 'server_gui_motorCurrent.py', 'argument1', 'argument2']) 164 | 165 | def motor_temp_monitor(): 166 | messagebox.showinfo("Display sensor data", "Motor Temperature data will be displayed in a new window") 167 | subprocess.call([sys.executable, 'server_gui_motorTemperature.py', 'argument1', 'argument2']) 168 | 169 | def write_motorSpeed_to_file(): 170 | messagebox.showinfo("Data to file", "Motor Speed data will be written to file KUKA_KR16_2_motorSpeed.csv") 171 | subprocess.call([sys.executable, 'server_gui_write_motorSpeed.py', 'argument1', 'argument2']) 172 | messagebox.showinfo("Data to file", "Motor Speed data was successfully written to file KUKA_KR16_2_motorSpeed.csv") 173 | 174 | def write_motorTorque_to_file(): 175 | messagebox.showinfo("Data to file", "Motor Torque data will be written to file KUKA_KR16_2_motorTorque.csv") 176 | subprocess.call([sys.executable, 'server_gui_write_motorTorque.py', 'argument1', 'argument2']) 177 | messagebox.showinfo("Data to file", "Motor Torque data was successfully written to file KUKA_KR16_2_motorTorque.csv") 178 | 179 | def write_motorCurrent_to_file(): 180 | messagebox.showinfo("Data to file", "Motor Current data will be written to file KUKA_KR16_2_motorCurrent.csv") 181 | subprocess.call([sys.executable, 'server_gui_write_motorCurrent.py', 'argument1', 'argument2']) 182 | messagebox.showinfo("Data to file", "Motor Current data was successfully written to file KUKA_KR16_2_motorCurrent.csv") 183 | 184 | def write_motorTemp_to_file(): 185 | messagebox.showinfo("Data to file", "Motor Temperature data will be written to file KUKA_KR16_2_motorTemp.csv") 186 | subprocess.call([sys.executable, 'server_gui_write_motorTemperature.py', 'argument1', 'argument2']) 187 | messagebox.showinfo("Data to file", "Motor Temperature data was successfully written to file KUKA_KR16_2_motorTemp.csv") 188 | 189 | app = KUKA_APP() 190 | app.mainloop() -------------------------------------------------------------------------------- /gui/server_gui_VC4_0.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Source code for an OPC UA server able to extract axis variables 3 | from a KUKA KR C4 robot controller and send them to an 4 | OPC UA client. 5 | 6 | Based on work by: 7 | - Massimiliano Fago (https://sourceforge.net/projects/openshowvar) 8 | - Mechatronics Lab at AAlesund University College 9 | (https://github.com/aauc-mechlab/JOpenShowVar) 10 | - Ahmad Saeed (https://github.com/akselov/kukavarproxy-msg-format) 11 | - Olivier Roulet-Dubonnet (https://github.com/FreeOpcUa) 12 | 13 | Author: Aksel Oevern 14 | NTNU 2018 15 | ''' 16 | 17 | import sys 18 | import socket 19 | sys.path.insert(0, "..") 20 | import time 21 | from opcua import ua, Server 22 | 23 | class KUKA(object): 24 | # Open socket 25 | # KukaVarProxy actively listens on TCP port 7000 26 | def __init__(self, TCP_IP): 27 | try: 28 | client.connect((TCP_IP, 7000)) 29 | except: 30 | self.error_list(1) 31 | 32 | # Sending messages on the KukaVarProxy message format: 33 | # Msg ID in HEX 2 bytes 34 | # Msg length in HEX 2 bytes 35 | # Read (0) or write (1) 1 byte 36 | # Variable name length in HEX 2 bytes 37 | # Variable name in ASCII # bytes 38 | # Variable value length in HEX 2 bytes 39 | # Variable value in ASCII # bytes 40 | def send (self, var, val, msgID): 41 | try: 42 | msg = bytearray() 43 | temp = bytearray() 44 | if val != "": 45 | val = str(val) 46 | msg.append((len(val) & 0xff00) >> 8) 47 | msg.append((len(val) & 0x00ff)) 48 | msg.extend(map(ord, val)) 49 | temp.append(bool(val)) 50 | temp.append(((len(var)) & 0xff00) >> 8) 51 | temp.append((len(var)) & 0x00ff) 52 | temp.extend(map(ord, var)) 53 | msg = temp + msg 54 | del temp[:] 55 | temp.append((msgID & 0xff00) >> 8) 56 | temp.append(msgID & 0x00ff) 57 | temp.append((len(msg) & 0xff00) >> 8) 58 | temp.append((len(msg) & 0x00ff)) 59 | msg = temp + msg 60 | except : 61 | self.error_list(2) 62 | try: 63 | client.send(msg) 64 | return client.recv(1024) 65 | except : 66 | self.error_list(1) 67 | 68 | # Get variables from KukaVarProxy response format 69 | def __get_var(self, msg): 70 | try: 71 | lsb = int( msg[5]) 72 | msb = int( msg[6]) 73 | lenValue = (lsb <<8 | msb) 74 | return str(msg [7: 7+lenValue],'utf-8') 75 | except: 76 | self.error_list(2) 77 | 78 | # Read variables from KukaVarProxy 79 | def read (self, var, msgID=0): 80 | try: 81 | return self.__get_var(self.send(var,"",msgID)) 82 | except : 83 | self.error_list(2) 84 | 85 | # Write variables to KukaVarProxy 86 | def write (self, var, val, msgID=0): 87 | try: 88 | if val != (""): 89 | return self.__get_var(self.send(var,val,msgID)) 90 | else: 91 | raise self.error_list(3) 92 | except : 93 | self.error_list(2) 94 | 95 | # Close socket 96 | def disconnect (self): 97 | client.close() 98 | 99 | # In case of error 100 | def error_list (self, ID): 101 | if ID == 1: 102 | print ("Network Error (tcp_error)") 103 | print ("Check your KRC's IP address on the network, and make sure kukaproxyvar is running.") 104 | self.disconnect() 105 | raise SystemExit 106 | elif ID == 2: 107 | print ("Python Error.") 108 | print ("Check the code and uncomment the lines related to your python version.") 109 | self.disconnect() 110 | raise SystemExit 111 | elif ID == 3: 112 | print ("Error in write() statement.") 113 | print ("Variable value is not defined.") 114 | 115 | if __name__ == "__main__": 116 | # Initialize OPC-UA Client connection 117 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 118 | 119 | # Setup robot object 120 | robot = KUKA('192.168.250.16') 121 | 122 | # Setup OPC-UA Server 123 | server = Server() 124 | server.set_endpoint("opc.tcp://192.168.250.200:50895") 125 | 126 | # Setup namespace 127 | uri = "http://examples.freeopcua.github.io" 128 | idx = server.register_namespace(uri) 129 | 130 | # Get objects node 131 | objects = server.get_objects_node() 132 | 133 | # Populating address space 134 | myObject = objects.add_object(idx, "KUKA_KR16_2") 135 | 136 | # Adding desired variables 137 | A1 = myObject.add_variable(idx, "A1", 6.7) 138 | A2 = myObject.add_variable(idx, "A2", 6.7) 139 | A3 = myObject.add_variable(idx, "A3", 6.7) 140 | A4 = myObject.add_variable(idx, "A4", 6.7) 141 | A5 = myObject.add_variable(idx, "A5", 6.7) 142 | A6 = myObject.add_variable(idx, "A6", 6.7) 143 | 144 | A1.set_writable() 145 | A2.set_writable() 146 | A3.set_writable() 147 | A4.set_writable() 148 | A5.set_writable() 149 | A6.set_writable() 150 | 151 | # Starting OPC-UA Server 152 | server.start() 153 | 154 | try: 155 | while(True): 156 | time.sleep(0.1) 157 | 158 | output = robot.read("$AXIS_ACT") 159 | output = output.replace(",", "") 160 | output_elements = output.split(" ") 161 | 162 | A1.set_value(output_elements[2]) 163 | A2.set_value(output_elements[4]) 164 | A3.set_value(output_elements[6]) 165 | A4.set_value(output_elements[8]) 166 | A5.set_value(output_elements[10]) 167 | A6.set_value(output_elements[12]) 168 | 169 | finally: 170 | # Close OPC UA client connection, remove subcsriptions, etc 171 | server.stop() -------------------------------------------------------------------------------- /gui/server_gui_motorCurrent.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Source code for an OPC UA server able to extract axis variables 3 | from a KUKA KR C4 robot controller and send them to an 4 | OPC UA client. The server also extracts information about the 5 | current going into each of the motors controlling the different 6 | KUKA robot axis and does a real-time plot of all the values. 7 | 8 | Based on work by: 9 | - Massimiliano Fago (https://sourceforge.net/projects/openshowvar) 10 | - Mechatronics Lab at AAlesund University College 11 | (https://github.com/aauc-mechlab/JOpenShowVar) 12 | - Ahmad Saeed (https://github.com/akselov/kukavarproxy-msg-format) 13 | - Olivier Roulet-Dubonnet (https://github.com/FreeOpcUa) 14 | 15 | Author: Aksel Oevern 16 | NTNU 2018 17 | ''' 18 | 19 | import sys 20 | import socket 21 | sys.path.insert(0, "..") 22 | import time 23 | import numpy as np 24 | import matplotlib.pyplot as plt 25 | from opcua import ua, Server 26 | 27 | class KUKA(object): 28 | # Open socket 29 | # KukaVarProxy actively listens on TCP port 7000 30 | def __init__(self, TCP_IP): 31 | try: 32 | client.connect((TCP_IP, 7000)) 33 | except: 34 | self.error_list(1) 35 | 36 | # Sending messages on the KukaVarProxy message format: 37 | # Msg ID in HEX 2 bytes 38 | # Msg length in HEX 2 bytes 39 | # Read (0) or write (1) 1 byte 40 | # Variable name length in HEX 2 bytes 41 | # Variable name in ASCII # bytes 42 | # Variable value length in HEX 2 bytes 43 | # Variable value in ASCII # bytes 44 | def send (self, var, val, msgID): 45 | try: 46 | msg = bytearray() 47 | temp = bytearray() 48 | if val != "": 49 | val = str(val) 50 | msg.append((len(val) & 0xff00) >> 8) 51 | msg.append((len(val) & 0x00ff)) 52 | msg.extend(map(ord, val)) 53 | temp.append(bool(val)) 54 | temp.append(((len(var)) & 0xff00) >> 8) 55 | temp.append((len(var)) & 0x00ff) 56 | temp.extend(map(ord, var)) 57 | msg = temp + msg 58 | del temp[:] 59 | temp.append((msgID & 0xff00) >> 8) 60 | temp.append(msgID & 0x00ff) 61 | temp.append((len(msg) & 0xff00) >> 8) 62 | temp.append((len(msg) & 0x00ff)) 63 | msg = temp + msg 64 | except : 65 | self.error_list(2) 66 | try: 67 | client.send(msg) 68 | return client.recv(1024) 69 | except : 70 | self.error_list(1) 71 | 72 | # Get variables from KukaVarProxy response format 73 | def __get_var(self, msg): 74 | try: 75 | lsb = int( msg[5]) 76 | msb = int( msg[6]) 77 | lenValue = (lsb <<8 | msb) 78 | return str(msg [7: 7+lenValue],'utf-8') 79 | except: 80 | self.error_list(2) 81 | 82 | # Read variables from KukaVarProxy 83 | def read (self, var, msgID=0): 84 | try: 85 | return self.__get_var(self.send(var,"",msgID)) 86 | except : 87 | self.error_list(2) 88 | 89 | # Write variables to KukaVarProxy 90 | def write (self, var, val, msgID=0): 91 | try: 92 | if val != (""): return self.__get_var(self.send(var,val,msgID)) 93 | else: raise self.error_list(3) 94 | except : 95 | self.error_list(2) 96 | 97 | # Close socket 98 | def disconnect (self): 99 | client.close() 100 | 101 | # In case of error 102 | def error_list (self, ID): 103 | if ID == 1: 104 | print ("Network Error (tcp_error)") 105 | print ("Check your KRC's IP address on the network, and make sure kukaproxyvar is running.") 106 | self.disconnect() 107 | raise SystemExit 108 | elif ID == 2: 109 | print ("Python Error.") 110 | print ("Check the code and uncomment the lines related to your python version.") 111 | self.disconnect() 112 | raise SystemExit 113 | elif ID == 3: 114 | print ("Error in write() statement.") 115 | print ("Variable value is not defined.") 116 | 117 | if __name__ == "__main__": 118 | # Initialize OPC-UA Client connection 119 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 120 | 121 | # Setup robot object 122 | robot = KUKA('192.168.250.16') 123 | 124 | # Setup server 125 | server = Server() 126 | server.set_endpoint("opc.tcp://192.168.250.200:50895") 127 | 128 | # Setup namespace 129 | uri = "http://examples.freeopcua.github.io" 130 | idx = server.register_namespace(uri) 131 | 132 | # Get objects node 133 | objects = server.get_objects_node() 134 | 135 | # Populating address space 136 | myObject = objects.add_object(idx, "KUKA_KR16_2") 137 | 138 | # Adding desired variables 139 | A1 = myObject.add_variable(idx, "A1", 6.7) 140 | A2 = myObject.add_variable(idx, "A2", 6.7) 141 | A3 = myObject.add_variable(idx, "A3", 6.7) 142 | A4 = myObject.add_variable(idx, "A4", 6.7) 143 | A5 = myObject.add_variable(idx, "A5", 6.7) 144 | A6 = myObject.add_variable(idx, "A6", 6.7) 145 | 146 | A1.set_writable() 147 | A2.set_writable() 148 | A3.set_writable() 149 | A4.set_writable() 150 | A5.set_writable() 151 | A6.set_writable() 152 | 153 | # Starting OPC-UA Server 154 | server.start() 155 | 156 | # Start plot 157 | xaxis_t0 = 100 158 | plt.axis([0, xaxis_t0, -100, 100]) 159 | plt.title('Actual Current of Axes KUKA KR 16-2, Axis 1-6') 160 | plt.grid(True) 161 | plt.xlabel('time [s*10]') 162 | plt.ylabel('Current [%]') 163 | plt.ion() 164 | count = 0 165 | 166 | plotted_values_A1 = [] 167 | plotted_values_A2 = [] 168 | plotted_values_A3 = [] 169 | plotted_values_A4 = [] 170 | plotted_values_A5 = [] 171 | plotted_values_A6 = [] 172 | 173 | plt.plot(plotted_values_A1, 'b', label='Axis 1') 174 | plt.plot(plotted_values_A2, 'r', label='Axis 2') 175 | plt.plot(plotted_values_A3, 'g', label='Axis 3') 176 | plt.plot(plotted_values_A4, 'c', label='Axis 4') 177 | plt.plot(plotted_values_A5, 'm', label='Axis 5') 178 | plt.plot(plotted_values_A6, 'y', label='Axis 6') 179 | 180 | plt.legend() 181 | 182 | try: 183 | count = 0 184 | while True: 185 | time.sleep(0.1) 186 | 187 | output = robot.read("$AXIS_ACT") 188 | output = output.replace(",", "") 189 | output_elements = output.split(" ") 190 | 191 | A1.set_value(output_elements[2]) 192 | A2.set_value(output_elements[4]) 193 | A3.set_value(output_elements[6]) 194 | A4.set_value(output_elements[8]) 195 | A5.set_value(output_elements[10]) 196 | A6.set_value(output_elements[12]) 197 | 198 | plotted_values_A1.append(float(robot.read("$CURR_ACT [1]"))) 199 | plotted_values_A2.append(float(robot.read("$CURR_ACT [2]"))) 200 | plotted_values_A3.append(float(robot.read("$CURR_ACT [3]"))) 201 | plotted_values_A4.append(float(robot.read("$CURR_ACT [4]"))) 202 | plotted_values_A5.append(float(robot.read("$CURR_ACT [5]"))) 203 | plotted_values_A6.append(float(robot.read("$CURR_ACT [6]"))) 204 | 205 | plt.plot(plotted_values_A1, 'b', label='Axis 1') 206 | plt.plot(plotted_values_A2, 'r', label='Axis 2') 207 | plt.plot(plotted_values_A3, 'g', label='Axis 3') 208 | plt.plot(plotted_values_A4, 'c', label='Axis 4') 209 | plt.plot(plotted_values_A5, 'm', label='Axis 5') 210 | plt.plot(plotted_values_A6, 'y', label='Axis 6') 211 | 212 | plt.pause(0.00001) 213 | count+=1 214 | 215 | # Resizing plot 216 | if(count+20 > xaxis_t0): 217 | xaxis_t0+=50 218 | plt.axis([0, xaxis_t0, -100, 100]) 219 | 220 | finally: 221 | # Close OPC UA client connection, remove subcsriptions, etc 222 | server.stop() -------------------------------------------------------------------------------- /gui/server_gui_motorSpeed.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Source code for an OPC UA server able to extract axis variables 3 | from a KUKA KR C4 robot controller and send them to an 4 | OPC UA client. The server also extracts information about the 5 | current velocity of each of the motors controlling the different 6 | KUKA robot axis and does a real-time plot of all the values. 7 | 8 | Based on work by: 9 | - Massimiliano Fago (https://sourceforge.net/projects/openshowvar) 10 | - Mechatronics Lab at AAlesund University College 11 | (https://github.com/aauc-mechlab/JOpenShowVar) 12 | - Ahmad Saeed (https://github.com/akselov/kukavarproxy-msg-format) 13 | - Olivier Roulet-Dubonnet (https://github.com/FreeOpcUa) 14 | 15 | Author: Aksel Oevern 16 | NTNU 2018 17 | ''' 18 | 19 | import sys 20 | import socket 21 | sys.path.insert(0, "..") 22 | import time 23 | import numpy as np 24 | import matplotlib.pyplot as plt 25 | from opcua import ua, Server 26 | 27 | class KUKA(object): 28 | # Open socket 29 | # KukaVarProxy actively listens on TCP port 7000 30 | def __init__(self, TCP_IP): 31 | try: 32 | client.connect((TCP_IP, 7000)) 33 | except: 34 | self.error_list(1) 35 | 36 | # Sending messages on the KukaVarProxy message format: 37 | # Msg ID in HEX 2 bytes 38 | # Msg length in HEX 2 bytes 39 | # Read (0) or write (1) 1 byte 40 | # Variable name length in HEX 2 bytes 41 | # Variable name in ASCII # bytes 42 | # Variable value length in HEX 2 bytes 43 | # Variable value in ASCII # bytes 44 | def send (self, var, val, msgID): 45 | try: 46 | msg = bytearray() 47 | temp = bytearray() 48 | if val != "": 49 | val = str(val) 50 | msg.append((len(val) & 0xff00) >> 8) 51 | msg.append((len(val) & 0x00ff)) 52 | msg.extend(map(ord, val)) 53 | temp.append(bool(val)) 54 | temp.append(((len(var)) & 0xff00) >> 8) 55 | temp.append((len(var)) & 0x00ff) 56 | temp.extend(map(ord, var)) 57 | msg = temp + msg 58 | del temp[:] 59 | temp.append((msgID & 0xff00) >> 8) 60 | temp.append(msgID & 0x00ff) 61 | temp.append((len(msg) & 0xff00) >> 8) 62 | temp.append((len(msg) & 0x00ff)) 63 | msg = temp + msg 64 | except : 65 | self.error_list(2) 66 | try: 67 | client.send(msg) 68 | return client.recv(1024) 69 | except : 70 | self.error_list(1) 71 | 72 | # Get variables from KukaVarProxy response format 73 | def __get_var(self, msg): 74 | try: 75 | lsb = int( msg[5]) 76 | msb = int( msg[6]) 77 | lenValue = (lsb <<8 | msb) 78 | return str(msg [7: 7+lenValue],'utf-8') 79 | except: 80 | self.error_list(2) 81 | 82 | # Read variables from KukaVarProxy 83 | def read (self, var, msgID=0): 84 | try: 85 | return self.__get_var(self.send(var,"",msgID)) 86 | except : 87 | self.error_list(2) 88 | 89 | # Write variables to KukaVarProxy 90 | def write (self, var, val, msgID=0): 91 | try: 92 | if val != (""): return self.__get_var(self.send(var,val,msgID)) 93 | else: raise self.error_list(3) 94 | except : 95 | self.error_list(2) 96 | 97 | # Close socket 98 | def disconnect (self): 99 | client.close() # CLose socket 100 | 101 | # In case of error 102 | def error_list (self, ID): 103 | if ID == 1: 104 | print ("Network Error (tcp_error)") 105 | print ("Check your KRC's IP address on the network, and make sure kukaproxyvar is running.") 106 | self.disconnect() 107 | raise SystemExit 108 | elif ID == 2: 109 | print ("Python Error.") 110 | print ("Check the code and uncomment the lines related to your python version.") 111 | self.disconnect() 112 | raise SystemExit 113 | elif ID == 3: 114 | print ("Error in write() statement.") 115 | print ("Variable value is not defined.") 116 | 117 | if __name__ == "__main__": 118 | # Initialize OPC-UA Client connection 119 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 120 | 121 | # Setup robot object 122 | robot = KUKA('192.168.250.16') 123 | 124 | # Setup server 125 | server = Server() 126 | server.set_endpoint("opc.tcp://192.168.250.200:50895") 127 | 128 | # Setup namespace 129 | uri = "http://examples.freeopcua.github.io" 130 | idx = server.register_namespace(uri) 131 | 132 | # Get objects node 133 | objects = server.get_objects_node() 134 | 135 | # Populating address space 136 | myObject = objects.add_object(idx, "KUKA_KR16_2") 137 | 138 | # Adding desired variables 139 | A1 = myObject.add_variable(idx, "A1", 6.7) 140 | A2 = myObject.add_variable(idx, "A2", 6.7) 141 | A3 = myObject.add_variable(idx, "A3", 6.7) 142 | A4 = myObject.add_variable(idx, "A4", 6.7) 143 | A5 = myObject.add_variable(idx, "A5", 6.7) 144 | A6 = myObject.add_variable(idx, "A6", 6.7) 145 | 146 | A1.set_writable() 147 | A2.set_writable() 148 | A3.set_writable() 149 | A4.set_writable() 150 | A5.set_writable() 151 | A6.set_writable() 152 | 153 | # Starting OPC-UA Server 154 | server.start() 155 | 156 | # Start plot 157 | xaxis_t0 = 100 158 | plt.axis([0, xaxis_t0, -100, 100]) 159 | plt.title('Current motor speed of KUKA KR 16-2, Axis 1-6') 160 | plt.grid(True) 161 | plt.xlabel('time [s*10]') 162 | plt.ylabel('Current motor speed [%]') 163 | plt.ion() 164 | count = 0 165 | 166 | plotted_values_A1 = [] 167 | plotted_values_A2 = [] 168 | plotted_values_A3 = [] 169 | plotted_values_A4 = [] 170 | plotted_values_A5 = [] 171 | plotted_values_A6 = [] 172 | 173 | plt.plot(plotted_values_A1, 'b', label='Axis 1') 174 | plt.plot(plotted_values_A2, 'r', label='Axis 2') 175 | plt.plot(plotted_values_A3, 'g', label='Axis 3') 176 | plt.plot(plotted_values_A4, 'c', label='Axis 4') 177 | plt.plot(plotted_values_A5, 'm', label='Axis 5') 178 | plt.plot(plotted_values_A6, 'y', label='Axis 6') 179 | 180 | plt.legend() 181 | 182 | try: 183 | count = 0 184 | while True: 185 | time.sleep(0.1) 186 | 187 | output = robot.read("$AXIS_ACT") 188 | output = output.replace(",", "") 189 | output_elements = output.split(" ") 190 | 191 | A1.set_value(output_elements[2]) 192 | A2.set_value(output_elements[4]) 193 | A3.set_value(output_elements[6]) 194 | A4.set_value(output_elements[8]) 195 | A5.set_value(output_elements[10]) 196 | A6.set_value(output_elements[12]) 197 | 198 | plotted_values_A1.append(float(robot.read("$VEL_AXIS_ACT [1]"))) 199 | plotted_values_A2.append(float(robot.read("$VEL_AXIS_ACT [2]"))) 200 | plotted_values_A3.append(float(robot.read("$VEL_AXIS_ACT [3]"))) 201 | plotted_values_A4.append(float(robot.read("$VEL_AXIS_ACT [4]"))) 202 | plotted_values_A5.append(float(robot.read("$VEL_AXIS_ACT [5]"))) 203 | plotted_values_A6.append(float(robot.read("$VEL_AXIS_ACT [6]"))) 204 | 205 | plt.plot(plotted_values_A1, 'b', label='Axis 1') 206 | plt.plot(plotted_values_A2, 'r', label='Axis 2') 207 | plt.plot(plotted_values_A3, 'g', label='Axis 3') 208 | plt.plot(plotted_values_A4, 'c', label='Axis 4') 209 | plt.plot(plotted_values_A5, 'm', label='Axis 5') 210 | plt.plot(plotted_values_A6, 'y', label='Axis 6') 211 | 212 | plt.pause(0.00001) 213 | count+=1 214 | 215 | # Resizing plot 216 | if(count+20 > xaxis_t0): 217 | xaxis_t0+=50 218 | plt.axis([0, xaxis_t0, -100, 100]) 219 | 220 | finally: 221 | # Close OPC UA client connection, remove subcsriptions, etc 222 | server.stop() -------------------------------------------------------------------------------- /gui/server_gui_motorTemperature.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Source code for an OPC UA server able to extract axis variables 3 | from a KUKA KR C4 robot controller and send them to an 4 | OPC UA client. The server also extracts information about the 5 | current velocity of each of the motors controlling the different 6 | KUKA robot axis and does a real-time plot of all the values. 7 | 8 | Based on work by: 9 | - Massimiliano Fago (https://sourceforge.net/projects/openshowvar) 10 | - Mechatronics Lab at AAlesund University College 11 | (https://github.com/aauc-mechlab/JOpenShowVar) 12 | - Ahmad Saeed (https://github.com/akselov/kukavarproxy-msg-format) 13 | - Olivier Roulet-Dubonnet (https://github.com/FreeOpcUa) 14 | 15 | Author: Aksel Oevern 16 | NTNU 2018 17 | ''' 18 | 19 | import sys 20 | import socket 21 | sys.path.insert(0, "..") 22 | import time 23 | import numpy as np 24 | import matplotlib.pyplot as plt 25 | import matplotlib.colors as clr 26 | from opcua import ua, Server 27 | 28 | class KUKA(object): 29 | # Open socket 30 | # KukaVarProxy actively listens on TCP port 7000 31 | def __init__(self, TCP_IP): 32 | try: 33 | client.connect((TCP_IP, 7000)) 34 | except: 35 | self.error_list(1) 36 | 37 | # Sending messages on the KukaVarProxy message format: 38 | # Msg ID in HEX 2 bytes 39 | # Msg length in HEX 2 bytes 40 | # Read (0) or write (1) 1 byte 41 | # Variable name length in HEX 2 bytes 42 | # Variable name in ASCII # bytes 43 | # Variable value length in HEX 2 bytes 44 | # Variable value in ASCII # bytes 45 | def send (self, var, val, msgID): 46 | try: 47 | msg = bytearray() 48 | temp = bytearray() 49 | if val != "": 50 | val = str(val) 51 | msg.append((len(val) & 0xff00) >> 8) 52 | msg.append((len(val) & 0x00ff)) 53 | msg.extend(map(ord, val)) 54 | temp.append(bool(val)) 55 | temp.append(((len(var)) & 0xff00) >> 8) 56 | temp.append((len(var)) & 0x00ff) 57 | temp.extend(map(ord, var)) 58 | msg = temp + msg 59 | del temp[:] 60 | temp.append((msgID & 0xff00) >> 8) 61 | temp.append(msgID & 0x00ff) 62 | temp.append((len(msg) & 0xff00) >> 8) 63 | temp.append((len(msg) & 0x00ff)) 64 | msg = temp + msg 65 | except : 66 | self.error_list(2) 67 | try: 68 | client.send(msg) 69 | return client.recv(1024) 70 | except : 71 | self.error_list(1) 72 | 73 | # Get variables from KukaVarProxy response format 74 | def __get_var(self, msg): 75 | try: 76 | lsb = int( msg[5]) 77 | msb = int( msg[6]) 78 | lenValue = (lsb <<8 | msb) 79 | return str(msg [7: 7+lenValue],'utf-8') 80 | except: 81 | self.error_list(2) 82 | 83 | # Read variables from KukaVarProxy 84 | def read (self, var, msgID=0): 85 | try: 86 | return self.__get_var(self.send(var,"",msgID)) 87 | except : 88 | self.error_list(2) 89 | 90 | # Write variables to KukaVarProxy 91 | def write (self, var, val, msgID=0): 92 | try: 93 | if val != (""): return self.__get_var(self.send(var,val,msgID)) 94 | else: raise self.error_list(3) 95 | except : 96 | self.error_list(2) 97 | 98 | # Close socket 99 | def disconnect (self): 100 | client.close() 101 | 102 | # In case of error 103 | def error_list (self, ID): 104 | if ID == 1: 105 | print ("Network Error (tcp_error)") 106 | print ("Check your KRC's IP address on the network, and make sure kukaproxyvar is running.") 107 | self.disconnect() 108 | raise SystemExit 109 | elif ID == 2: 110 | print ("Python Error.") 111 | print ("Check the code and uncomment the lines related to your python version.") 112 | self.disconnect() 113 | raise SystemExit 114 | elif ID == 3: 115 | print ("Error in write() statement.") 116 | print ("Variable value is not defined.") 117 | 118 | # Plot figure 119 | def plot_fig(xmin, xmax, ymin, ymax): 120 | plt.axis([xmin, xmax, ymin, ymax]) 121 | plt.title('Current motor temperature of KUKA KR 16-2, Axis 1-6') 122 | plt.grid(True) 123 | plt.xlabel('time [s*10]') 124 | plt.ylabel('Motor temperature [' + u'\u2103' + ']') 125 | plt.ion() 126 | 127 | # Construct a colormap 128 | cmap = clr.LinearSegmentedColormap.from_list('cmap for Dennis Hein', [(0, '#ff0000'), (70/100., '#ffff00'), (100/100., '#00ff00')], N=64) 129 | X = [[.0, .0], [1.0, 1.0]] 130 | plt.imshow(X, interpolation='bicubic', cmap = cmap, extent=(xmin, xmax, ymin, ymax), alpha = 0.3) 131 | 132 | def plot_values(): 133 | plt.plot(plotted_values_A1, 'b', label='Axis 1') 134 | plt.plot(plotted_values_A2, 'r', label='Axis 2') 135 | plt.plot(plotted_values_A3, 'g', label='Axis 3') 136 | plt.plot(plotted_values_A4, 'c', label='Axis 4') 137 | plt.plot(plotted_values_A5, 'm', label='Axis 5') 138 | plt.plot(plotted_values_A6, 'y', label='Axis 6') 139 | 140 | if __name__ == "__main__": 141 | # Initialize OPC-UA Client connection 142 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 143 | 144 | # Setup robot object 145 | robot = KUKA('192.168.250.16') 146 | 147 | # Setup server 148 | server = Server() 149 | server.set_endpoint("opc.tcp://192.168.250.200:50895") 150 | 151 | # Setup namespace 152 | uri = "http://examples.freeopcua.github.io" 153 | idx = server.register_namespace(uri) 154 | 155 | # Get objects node 156 | objects = server.get_objects_node() 157 | 158 | # Populating address space 159 | myObject = objects.add_object(idx, "KUKA_KR16_2") 160 | 161 | # Adding desired variables 162 | A1 = myObject.add_variable(idx, "A1", 6.7) 163 | A2 = myObject.add_variable(idx, "A2", 6.7) 164 | A3 = myObject.add_variable(idx, "A3", 6.7) 165 | A4 = myObject.add_variable(idx, "A4", 6.7) 166 | A5 = myObject.add_variable(idx, "A5", 6.7) 167 | A6 = myObject.add_variable(idx, "A6", 6.7) 168 | 169 | A1.set_writable() 170 | A2.set_writable() 171 | A3.set_writable() 172 | A4.set_writable() 173 | A5.set_writable() 174 | A6.set_writable() 175 | 176 | # Starting OPC-UA Server 177 | server.start() 178 | 179 | # Start plot 180 | xmin, xmax, ymin, ymax = 0, 200, 15, 100 181 | plot_fig(xmin, xmax, ymin, ymax) 182 | 183 | count = 0 184 | 185 | plotted_values_A1 = [] 186 | plotted_values_A2 = [] 187 | plotted_values_A3 = [] 188 | plotted_values_A4 = [] 189 | plotted_values_A5 = [] 190 | plotted_values_A6 = [] 191 | 192 | plot_values() 193 | plt.legend() 194 | 195 | try: 196 | count = 0 197 | offset = 273.15 # Kelvin to celcius 198 | while True: 199 | time.sleep(0.1) 200 | 201 | output = robot.read("$AXIS_ACT") 202 | output = output.replace(",", "") 203 | output_elements = output.split(" ") 204 | 205 | A1.set_value(output_elements[2]) 206 | A2.set_value(output_elements[4]) 207 | A3.set_value(output_elements[6]) 208 | A4.set_value(output_elements[8]) 209 | A5.set_value(output_elements[10]) 210 | A6.set_value(output_elements[12]) 211 | 212 | plotted_values_A1.append(float(robot.read("$MOT_TEMP [1]")) - offset) 213 | plotted_values_A2.append(float(robot.read("$MOT_TEMP [2]")) - offset) 214 | plotted_values_A3.append(float(robot.read("$MOT_TEMP [3]")) - offset) 215 | plotted_values_A4.append(float(robot.read("$MOT_TEMP [4]")) - offset) 216 | plotted_values_A5.append(float(robot.read("$MOT_TEMP [5]")) - offset) 217 | plotted_values_A6.append(float(robot.read("$MOT_TEMP [6]")) - offset) 218 | 219 | plot_values() 220 | 221 | plt.pause(0.00001) 222 | count+=1 223 | 224 | # Resizing plot 225 | if(count+20 > xmax): 226 | xmin+=100 227 | xmax+=100 228 | plt.axis([xmin, xmax, ymin, ymax]) 229 | plt.clf() 230 | plot_fig(xmin, xmax, ymin, ymax) 231 | plot_values() 232 | plt.legend() 233 | 234 | finally: 235 | #close connection, remove subcsriptions, etc 236 | server.stop() -------------------------------------------------------------------------------- /gui/server_gui_motorTorque.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Source code for an OPC UA server able to extract axis variables 3 | from a KUKA KR C4 robot controller and send them to an 4 | OPC UA client. The server also extracts information about the 5 | current torque on each of the motors controlling the different 6 | KUKA robot axis and does a real-time plot of all the values. 7 | 8 | Based on work by: 9 | - Massimiliano Fago (https://sourceforge.net/projects/openshowvar) 10 | - Mechatronics Lab at AAlesund University College 11 | (https://github.com/aauc-mechlab/JOpenShowVar) 12 | - Ahmad Saeed (https://github.com/akselov/kukavarproxy-msg-format) 13 | - Olivier Roulet-Dubonnet (https://github.com/FreeOpcUa) 14 | 15 | Author: Aksel Oevern 16 | NTNU 2018 17 | ''' 18 | 19 | import sys 20 | import socket 21 | sys.path.insert(0, "..") 22 | import time 23 | import numpy as np 24 | import matplotlib.pyplot as plt 25 | from opcua import ua, Server 26 | 27 | class KUKA(object): 28 | # Open socket 29 | # KukaVarProxy actively listens on TCP port 7000 30 | def __init__(self, TCP_IP): 31 | try: 32 | client.connect((TCP_IP, 7000)) 33 | except: 34 | self.error_list(1) 35 | 36 | # Sending messages on the KukaVarProxy message format: 37 | # Msg ID in HEX 2 bytes 38 | # Msg length in HEX 2 bytes 39 | # Read (0) or write (1) 1 byte 40 | # Variable name length in HEX 2 bytes 41 | # Variable name in ASCII # bytes 42 | # Variable value length in HEX 2 bytes 43 | # Variable value in ASCII # bytes 44 | def send (self, var, val, msgID): 45 | try: 46 | msg = bytearray() 47 | temp = bytearray() 48 | if val != "": 49 | val = str(val) 50 | msg.append((len(val) & 0xff00) >> 8) 51 | msg.append((len(val) & 0x00ff)) 52 | msg.extend(map(ord, val)) 53 | temp.append(bool(val)) 54 | temp.append(((len(var)) & 0xff00) >> 8) 55 | temp.append((len(var)) & 0x00ff) 56 | temp.extend(map(ord, var)) 57 | msg = temp + msg 58 | del temp[:] 59 | temp.append((msgID & 0xff00) >> 8) 60 | temp.append(msgID & 0x00ff) 61 | temp.append((len(msg) & 0xff00) >> 8) 62 | temp.append((len(msg) & 0x00ff)) 63 | msg = temp + msg 64 | except : 65 | self.error_list(2) 66 | try: 67 | client.send(msg) 68 | return client.recv(1024) 69 | except : 70 | self.error_list(1) 71 | 72 | # Get variables from KukaVarProxy response format 73 | def __get_var(self, msg): 74 | try: 75 | lsb = int( msg[5]) 76 | msb = int( msg[6]) 77 | lenValue = (lsb <<8 | msb) 78 | return str(msg [7: 7+lenValue],'utf-8') 79 | except: 80 | self.error_list(2) 81 | 82 | # Read variables from KukaVarProxy 83 | def read (self, var, msgID=0): 84 | try: 85 | return self.__get_var(self.send(var,"",msgID)) 86 | except : 87 | self.error_list(2) 88 | 89 | # Write variables to KukaVarProxy 90 | def write (self, var, val, msgID=0): 91 | try: 92 | if val != (""): return self.__get_var(self.send(var,val,msgID)) 93 | else: raise self.error_list(3) 94 | except : 95 | self.error_list(2) 96 | 97 | # Close socket 98 | def disconnect (self): 99 | client.close() 100 | 101 | # In case of error 102 | def error_list (self, ID): 103 | if ID == 1: 104 | print ("Network Error (tcp_error)") 105 | print ("Check your KRC's IP address on the network, and make sure kukaproxyvar is running.") 106 | self.disconnect() 107 | raise SystemExit 108 | elif ID == 2: 109 | print ("Python Error.") 110 | print ("Check the code and uncomment the lines related to your python version.") 111 | self.disconnect() 112 | raise SystemExit 113 | elif ID == 3: 114 | print ("Error in write() statement.") 115 | print ("Variable value is not defined.") 116 | 117 | if __name__ == "__main__": 118 | # Initialize OPC-UA Client connection 119 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 120 | 121 | # Setup robot object 122 | robot = KUKA('192.168.250.16') 123 | 124 | # Setup server 125 | server = Server() 126 | server.set_endpoint("opc.tcp://192.168.250.200:50895") 127 | 128 | # Setup namespace 129 | uri = "http://examples.freeopcua.github.io" 130 | idx = server.register_namespace(uri) 131 | 132 | # Get objects node 133 | objects = server.get_objects_node() 134 | 135 | # Populating address space 136 | myObject = objects.add_object(idx, "KUKA_KR16_2") 137 | 138 | # Adding desired variables 139 | A1 = myObject.add_variable(idx, "A1", 6.7) 140 | A2 = myObject.add_variable(idx, "A2", 6.7) 141 | A3 = myObject.add_variable(idx, "A3", 6.7) 142 | A4 = myObject.add_variable(idx, "A4", 6.7) 143 | A5 = myObject.add_variable(idx, "A5", 6.7) 144 | A6 = myObject.add_variable(idx, "A6", 6.7) 145 | 146 | A1.set_writable() 147 | A2.set_writable() 148 | A3.set_writable() 149 | A4.set_writable() 150 | A5.set_writable() 151 | A6.set_writable() 152 | 153 | # Starting OPC-UA Server 154 | server.start() 155 | 156 | # Start plot 157 | xaxis_t0 = 100 158 | plt.axis([0, xaxis_t0, -1000, 1000]) 159 | plt.title('Current motor torque of KUKA KR 16-2, Axis 1-6') 160 | plt.grid(True) 161 | plt.xlabel('time [s*10]') 162 | plt.ylabel('Current motor torque [Nm]') 163 | plt.ion() 164 | count = 0 165 | 166 | plotted_values_A1 = [] 167 | plotted_values_A2 = [] 168 | plotted_values_A3 = [] 169 | plotted_values_A4 = [] 170 | plotted_values_A5 = [] 171 | plotted_values_A6 = [] 172 | 173 | plt.plot(plotted_values_A1, 'b', label='Axis 1') 174 | plt.plot(plotted_values_A2, 'r', label='Axis 2') 175 | plt.plot(plotted_values_A3, 'g', label='Axis 3') 176 | plt.plot(plotted_values_A4, 'c', label='Axis 4') 177 | plt.plot(plotted_values_A5, 'm', label='Axis 5') 178 | plt.plot(plotted_values_A6, 'y', label='Axis 6') 179 | 180 | plt.legend() 181 | 182 | try: 183 | count = 0 184 | while True: 185 | time.sleep(0.1) 186 | 187 | output = robot.read("$AXIS_ACT") 188 | output = output.replace(",", "") 189 | output_elements = output.split(" ") 190 | 191 | A1.set_value(output_elements[2]) 192 | A2.set_value(output_elements[4]) 193 | A3.set_value(output_elements[6]) 194 | A4.set_value(output_elements[8]) 195 | A5.set_value(output_elements[10]) 196 | A6.set_value(output_elements[12]) 197 | 198 | plotted_values_A1.append(float(robot.read("$TORQUE_AXIS_ACT [1]"))) 199 | plotted_values_A2.append(float(robot.read("$TORQUE_AXIS_ACT [2]"))) 200 | plotted_values_A3.append(float(robot.read("$TORQUE_AXIS_ACT [3]"))) 201 | plotted_values_A4.append(float(robot.read("$TORQUE_AXIS_ACT [4]"))) 202 | plotted_values_A5.append(float(robot.read("$TORQUE_AXIS_ACT [5]"))) 203 | plotted_values_A6.append(float(robot.read("$TORQUE_AXIS_ACT [6]"))) 204 | 205 | plt.plot(plotted_values_A1, 'b', label='Axis 1') 206 | plt.plot(plotted_values_A2, 'r', label='Axis 2') 207 | plt.plot(plotted_values_A3, 'g', label='Axis 3') 208 | plt.plot(plotted_values_A4, 'c', label='Axis 4') 209 | plt.plot(plotted_values_A5, 'm', label='Axis 5') 210 | plt.plot(plotted_values_A6, 'y', label='Axis 6') 211 | 212 | plt.pause(0.00001) 213 | count+=1 214 | 215 | # Resizing plot 216 | if(count+20 > xaxis_t0): 217 | xaxis_t0+=50 218 | plt.axis([0, xaxis_t0, -1000, 1000]) 219 | 220 | finally: 221 | # Close OPC UA client connection, remove subcsriptions, etc 222 | server.stop() -------------------------------------------------------------------------------- /gui/server_gui_write_motorCurrent.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Source code for an OPC UA server able to extract axis variables 3 | from a KUKA KR C4 robot controller and send them to an 4 | OPC UA client. The server also extracts information about the 5 | current of each of the motors controlling the different 6 | KUKA robot axis and writes the data to a .csv file called 7 | "KUKA_KR16_2_motorCurrent.csv". 8 | 9 | Based on work by: 10 | - Massimiliano Fago (https://sourceforge.net/projects/openshowvar) 11 | - Mechatronics Lab at AAlesund University College 12 | (https://github.com/aauc-mechlab/JOpenShowVar) 13 | - Ahmad Saeed (https://github.com/akselov/kukavarproxy-msg-format) 14 | - Olivier Roulet-Dubonnet (https://github.com/FreeOpcUa) 15 | 16 | Author: Aksel Oevern 17 | NTNU 2018 18 | ''' 19 | 20 | import sys 21 | import socket 22 | sys.path.insert(0, "..") 23 | import time 24 | from opcua import ua, Server 25 | 26 | class KUKA(object): 27 | # Open socket 28 | # KukaVarProxy actively listens on TCP port 7000 29 | def __init__(self, TCP_IP): 30 | try: 31 | client.connect((TCP_IP, 7000)) 32 | except: 33 | self.error_list(1) 34 | 35 | # Sending messages on the KukaVarProxy message format: 36 | # Msg ID in HEX 2 bytes 37 | # Msg length in HEX 2 bytes 38 | # Read (0) or write (1) 1 byte 39 | # Variable name length in HEX 2 bytes 40 | # Variable name in ASCII # bytes 41 | # Variable value length in HEX 2 bytes 42 | # Variable value in ASCII # bytes 43 | def send (self, var, val, msgID): 44 | try: 45 | msg = bytearray() 46 | temp = bytearray() 47 | if val != "": 48 | val = str(val) 49 | msg.append((len(val) & 0xff00) >> 8) 50 | msg.append((len(val) & 0x00ff)) 51 | msg.extend(map(ord, val)) 52 | temp.append(bool(val)) 53 | temp.append(((len(var)) & 0xff00) >> 8) 54 | temp.append((len(var)) & 0x00ff) 55 | temp.extend(map(ord, var)) 56 | msg = temp + msg 57 | del temp[:] 58 | temp.append((msgID & 0xff00) >> 8) 59 | temp.append(msgID & 0x00ff) 60 | temp.append((len(msg) & 0xff00) >> 8) 61 | temp.append((len(msg) & 0x00ff)) 62 | msg = temp + msg 63 | except : 64 | self.error_list(2) 65 | try: 66 | client.send(msg) 67 | return client.recv(1024) 68 | except : 69 | self.error_list(1) 70 | 71 | # Get variables from KukaVarProxy response format 72 | def __get_var(self, msg): 73 | try: 74 | lsb = int( msg[5]) 75 | msb = int( msg[6]) 76 | lenValue = (lsb <<8 | msb) 77 | return str(msg [7: 7+lenValue],'utf-8') 78 | except: 79 | self.error_list(2) 80 | 81 | # Read variables from KukaVarProxy 82 | def read (self, var, msgID=0): 83 | try: 84 | return self.__get_var(self.send(var,"",msgID)) 85 | except : 86 | self.error_list(2) 87 | 88 | # Write variables to KukaVarProxy 89 | def write (self, var, val, msgID=0): 90 | try: 91 | if val != (""): return self.__get_var(self.send(var,val,msgID)) 92 | else: raise self.error_list(3) 93 | except : 94 | self.error_list(2) 95 | 96 | # Close socket 97 | def disconnect (self): 98 | client.close() 99 | 100 | # In case of error 101 | def error_list (self, ID): 102 | if ID == 1: 103 | print ("Network Error (tcp_error)") 104 | print ("Check your KRC's IP address on the network, and make sure kukaproxyvar is running.") 105 | self.disconnect() 106 | raise SystemExit 107 | elif ID == 2: 108 | print ("Python Error.") 109 | print ("Check the code and uncomment the lines related to your python version.") 110 | self.disconnect() 111 | raise SystemExit 112 | elif ID == 3: 113 | print ("Error in write() statement.") 114 | print ("Variable value is not defined.") 115 | 116 | if __name__ == "__main__": 117 | # Initialize OPC-UA Client connection 118 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 119 | 120 | # Setup robot object 121 | robot = KUKA('192.168.250.16') 122 | 123 | # Setup server 124 | server = Server() 125 | server.set_endpoint("opc.tcp://192.168.250.200:50895") 126 | 127 | # Setup namespace 128 | uri = "http://examples.freeopcua.github.io" 129 | idx = server.register_namespace(uri) 130 | 131 | # Get objects node 132 | objects = server.get_objects_node() 133 | 134 | # Populating address space 135 | myObject = objects.add_object(idx, "KUKA_KR16_2") 136 | 137 | # Adding desired variables 138 | A1 = myObject.add_variable(idx, "A1", 6.7) 139 | A2 = myObject.add_variable(idx, "A2", 6.7) 140 | A3 = myObject.add_variable(idx, "A3", 6.7) 141 | A4 = myObject.add_variable(idx, "A4", 6.7) 142 | A5 = myObject.add_variable(idx, "A5", 6.7) 143 | A6 = myObject.add_variable(idx, "A6", 6.7) 144 | 145 | A1.set_writable() 146 | A2.set_writable() 147 | A3.set_writable() 148 | A4.set_writable() 149 | A5.set_writable() 150 | A6.set_writable() 151 | 152 | # Starting OPC-UA Server 153 | server.start() 154 | 155 | # Values to be written 156 | values_A1 = [] 157 | values_A2 = [] 158 | values_A3 = [] 159 | values_A4 = [] 160 | values_A5 = [] 161 | values_A6 = [] 162 | 163 | try: 164 | # Timer for monitoring interval 165 | count = 0 166 | timer = 100 167 | while(count < timer): 168 | time.sleep(0.1) 169 | count+=1 170 | 171 | output = robot.read("$AXIS_ACT") 172 | output = output.replace(",", "") 173 | output_elements = output.split(" ") 174 | 175 | A1.set_value(output_elements[2]) 176 | A2.set_value(output_elements[4]) 177 | A3.set_value(output_elements[6]) 178 | A4.set_value(output_elements[8]) 179 | A5.set_value(output_elements[10]) 180 | A6.set_value(output_elements[12]) 181 | 182 | values_A1.append(float(robot.read("$CURR_ACT [1]"))) 183 | values_A2.append(float(robot.read("$CURR_ACT [2]"))) 184 | values_A3.append(float(robot.read("$CURR_ACT [3]"))) 185 | values_A4.append(float(robot.read("$CURR_ACT [4]"))) 186 | values_A5.append(float(robot.read("$CURR_ACT [5]"))) 187 | values_A6.append(float(robot.read("$CURR_ACT [6]"))) 188 | 189 | f = open('KUKA_KR16_2_motorCurrent.csv', 'w') 190 | 191 | for i in range(0, len(values_A1)): 192 | f.write(str(values_A1[i]) + ",") 193 | f.write(str(values_A2[i]) + ",") 194 | f.write(str(values_A3[i]) + ",") 195 | f.write(str(values_A4[i]) + ",") 196 | f.write(str(values_A5[i]) + ",") 197 | f.write(str(values_A6[i]) + "\n") 198 | 199 | f.close() 200 | 201 | finally: 202 | # Close OPC UA client connection, remove subcsriptions, etc 203 | server.stop() -------------------------------------------------------------------------------- /gui/server_gui_write_motorSpeed.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Source code for an OPC UA server able to extract axis variables 3 | from a KUKA KR C4 robot controller and send them to an 4 | OPC UA client. The server also extracts information about the 5 | current velocity of each of the motors controlling the different 6 | KUKA robot axis and writes the data to a .csv file called 7 | "KUKA_KR16_2_motorSpeed.csv". 8 | 9 | Based on work by: 10 | - Massimiliano Fago (https://sourceforge.net/projects/openshowvar) 11 | - Mechatronics Lab at AAlesund University College 12 | (https://github.com/aauc-mechlab/JOpenShowVar) 13 | - Ahmad Saeed (https://github.com/akselov/kukavarproxy-msg-format) 14 | - Olivier Roulet-Dubonnet (https://github.com/FreeOpcUa) 15 | 16 | Author: Aksel Oevern 17 | NTNU 2018 18 | ''' 19 | 20 | import sys 21 | import socket 22 | sys.path.insert(0, "..") 23 | import time 24 | from opcua import ua, Server 25 | 26 | class KUKA(object): 27 | # Open socket 28 | # KukaVarProxy actively listens on TCP port 7000 29 | def __init__(self, TCP_IP): 30 | try: 31 | client.connect((TCP_IP, 7000)) 32 | except: 33 | self.error_list(1) 34 | 35 | # Sending messages on the KukaVarProxy message format: 36 | # Msg ID in HEX 2 bytes 37 | # Msg length in HEX 2 bytes 38 | # Read (0) or write (1) 1 byte 39 | # Variable name length in HEX 2 bytes 40 | # Variable name in ASCII # bytes 41 | # Variable value length in HEX 2 bytes 42 | # Variable value in ASCII # bytes 43 | def send (self, var, val, msgID): 44 | try: 45 | msg = bytearray() 46 | temp = bytearray() 47 | if val != "": 48 | val = str(val) 49 | msg.append((len(val) & 0xff00) >> 8) 50 | msg.append((len(val) & 0x00ff)) 51 | msg.extend(map(ord, val)) 52 | temp.append(bool(val)) 53 | temp.append(((len(var)) & 0xff00) >> 8) 54 | temp.append((len(var)) & 0x00ff) 55 | temp.extend(map(ord, var)) 56 | msg = temp + msg 57 | del temp[:] 58 | temp.append((msgID & 0xff00) >> 8) 59 | temp.append(msgID & 0x00ff) 60 | temp.append((len(msg) & 0xff00) >> 8) 61 | temp.append((len(msg) & 0x00ff)) 62 | msg = temp + msg 63 | except : 64 | self.error_list(2) 65 | try: 66 | client.send(msg) 67 | return client.recv(1024) 68 | except : 69 | self.error_list(1) 70 | 71 | # Get variables from KukaVarProxy response format 72 | def __get_var(self, msg): 73 | try: 74 | lsb = int( msg[5]) 75 | msb = int( msg[6]) 76 | lenValue = (lsb <<8 | msb) 77 | return str(msg [7: 7+lenValue],'utf-8') 78 | except: 79 | self.error_list(2) 80 | 81 | # Read variables from KukaVarProxy 82 | def read (self, var, msgID=0): 83 | try: 84 | return self.__get_var(self.send(var,"",msgID)) 85 | except : 86 | self.error_list(2) 87 | 88 | # Write variables to KukaVarProxy 89 | def write (self, var, val, msgID=0): 90 | try: 91 | if val != (""): return self.__get_var(self.send(var,val,msgID)) 92 | else: raise self.error_list(3) 93 | except : 94 | self.error_list(2) 95 | 96 | # Close socket 97 | def disconnect (self): 98 | client.close() 99 | 100 | # In case of error 101 | def error_list (self, ID): 102 | if ID == 1: 103 | print ("Network Error (tcp_error)") 104 | print ("Check your KRC's IP address on the network, and make sure kukaproxyvar is running.") 105 | self.disconnect() 106 | raise SystemExit 107 | elif ID == 2: 108 | print ("Python Error.") 109 | print ("Check the code and uncomment the lines related to your python version.") 110 | self.disconnect() 111 | raise SystemExit 112 | elif ID == 3: 113 | print ("Error in write() statement.") 114 | print ("Variable value is not defined.") 115 | 116 | if __name__ == "__main__": 117 | # Initialize OPC-UA Client connection 118 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 119 | 120 | # Setup robot object 121 | robot = KUKA('192.168.250.16') 122 | 123 | # Setup server 124 | server = Server() 125 | server.set_endpoint("opc.tcp://192.168.250.200:50895") 126 | 127 | # Setup namespace 128 | uri = "http://examples.freeopcua.github.io" 129 | idx = server.register_namespace(uri) 130 | 131 | # Get objects node 132 | objects = server.get_objects_node() 133 | 134 | # Populating address space 135 | myObject = objects.add_object(idx, "KUKA_KR16_2") 136 | 137 | # Adding desired variables 138 | A1 = myObject.add_variable(idx, "A1", 6.7) 139 | A2 = myObject.add_variable(idx, "A2", 6.7) 140 | A3 = myObject.add_variable(idx, "A3", 6.7) 141 | A4 = myObject.add_variable(idx, "A4", 6.7) 142 | A5 = myObject.add_variable(idx, "A5", 6.7) 143 | A6 = myObject.add_variable(idx, "A6", 6.7) 144 | 145 | A1.set_writable() 146 | A2.set_writable() 147 | A3.set_writable() 148 | A4.set_writable() 149 | A5.set_writable() 150 | A6.set_writable() 151 | 152 | # Starting OPC-UA Server 153 | server.start() 154 | 155 | # Values to be written 156 | values_A1 = [] 157 | values_A2 = [] 158 | values_A3 = [] 159 | values_A4 = [] 160 | values_A5 = [] 161 | values_A6 = [] 162 | 163 | try: 164 | # Timer for monitoring interval 165 | count = 0 166 | timer = 100 167 | while(count < timer): 168 | time.sleep(0.1) 169 | count+=1 170 | 171 | output = robot.read("$AXIS_ACT") 172 | output = output.replace(",", "") 173 | output_elements = output.split(" ") 174 | 175 | A1.set_value(output_elements[2]) 176 | A2.set_value(output_elements[4]) 177 | A3.set_value(output_elements[6]) 178 | A4.set_value(output_elements[8]) 179 | A5.set_value(output_elements[10]) 180 | A6.set_value(output_elements[12]) 181 | 182 | values_A1.append(float(robot.read("$VEL_AXIS_ACT [1]"))*10) 183 | values_A2.append(float(robot.read("$VEL_AXIS_ACT [2]"))*10) 184 | values_A3.append(float(robot.read("$VEL_AXIS_ACT [3]"))*10) 185 | values_A4.append(float(robot.read("$VEL_AXIS_ACT [4]"))*10) 186 | values_A5.append(float(robot.read("$VEL_AXIS_ACT [5]"))*10) 187 | values_A6.append(float(robot.read("$VEL_AXIS_ACT [6]"))*10) 188 | 189 | f = open('KUKA_KR16_2_motorSpeed.csv', 'w') 190 | 191 | for i in range(0, len(values_A1)): 192 | f.write(str(values_A1[i]) + ",") 193 | f.write(str(values_A2[i]) + ",") 194 | f.write(str(values_A3[i]) + ",") 195 | f.write(str(values_A4[i]) + ",") 196 | f.write(str(values_A5[i]) + ",") 197 | f.write(str(values_A6[i]) + "\n") 198 | 199 | f.close() 200 | 201 | finally: 202 | # Close OPC UA client connection, remove subcsriptions, etc 203 | server.stop() -------------------------------------------------------------------------------- /gui/server_gui_write_motorTemperature.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Source code for an OPC UA server able to extract axis variables 3 | from a KUKA KR C4 robot controller and send them to an 4 | OPC UA client. The server also extracts information about the 5 | current temperature of each of the motors controlling the different 6 | KUKA robot axis and writes the data to a .csv file called 7 | "KUKA_KR16_2_motorTemp.csv". 8 | 9 | Based on work by: 10 | - Massimiliano Fago (https://sourceforge.net/projects/openshowvar) 11 | - Mechatronics Lab at AAlesund University College 12 | (https://github.com/aauc-mechlab/JOpenShowVar) 13 | - Ahmad Saeed (https://github.com/akselov/kukavarproxy-msg-format) 14 | - Olivier Roulet-Dubonnet (https://github.com/FreeOpcUa) 15 | 16 | Author: Aksel Oevern 17 | NTNU 2018 18 | ''' 19 | 20 | import sys 21 | import socket 22 | sys.path.insert(0, "..") 23 | import time 24 | from opcua import ua, Server 25 | 26 | class KUKA(object): 27 | # Open socket 28 | # KukaVarProxy actively listens on TCP port 7000 29 | def __init__(self, TCP_IP): 30 | try: 31 | client.connect((TCP_IP, 7000)) 32 | except: 33 | self.error_list(1) 34 | 35 | # Sending messages on the KukaVarProxy message format: 36 | # Msg ID in HEX 2 bytes 37 | # Msg length in HEX 2 bytes 38 | # Read (0) or write (1) 1 byte 39 | # Variable name length in HEX 2 bytes 40 | # Variable name in ASCII # bytes 41 | # Variable value length in HEX 2 bytes 42 | # Variable value in ASCII # bytes 43 | def send (self, var, val, msgID): 44 | try: 45 | msg = bytearray() 46 | temp = bytearray() 47 | if val != "": 48 | val = str(val) 49 | msg.append((len(val) & 0xff00) >> 8) 50 | msg.append((len(val) & 0x00ff)) 51 | msg.extend(map(ord, val)) 52 | temp.append(bool(val)) 53 | temp.append(((len(var)) & 0xff00) >> 8) 54 | temp.append((len(var)) & 0x00ff) 55 | temp.extend(map(ord, var)) 56 | msg = temp + msg 57 | del temp[:] 58 | temp.append((msgID & 0xff00) >> 8) 59 | temp.append(msgID & 0x00ff) 60 | temp.append((len(msg) & 0xff00) >> 8) 61 | temp.append((len(msg) & 0x00ff)) 62 | msg = temp + msg 63 | except : 64 | self.error_list(2) 65 | try: 66 | client.send(msg) 67 | return client.recv(1024) 68 | except : 69 | self.error_list(1) 70 | 71 | # Get variables from KukaVarProxy response format 72 | def __get_var(self, msg): 73 | try: 74 | lsb = int( msg[5]) 75 | msb = int( msg[6]) 76 | lenValue = (lsb <<8 | msb) 77 | return str(msg [7: 7+lenValue],'utf-8') 78 | except: 79 | self.error_list(2) 80 | 81 | # Read variables from KukaVarProxy 82 | def read (self, var, msgID=0): 83 | try: 84 | return self.__get_var(self.send(var,"",msgID)) 85 | except : 86 | self.error_list(2) 87 | 88 | # Write variables to KukaVarProxy 89 | def write (self, var, val, msgID=0): 90 | try: 91 | if val != (""): return self.__get_var(self.send(var,val,msgID)) 92 | else: raise self.error_list(3) 93 | except : 94 | self.error_list(2) 95 | 96 | # Close socket 97 | def disconnect (self): 98 | client.close() 99 | 100 | # In case of error 101 | def error_list (self, ID): 102 | if ID == 1: 103 | print ("Network Error (tcp_error)") 104 | print ("Check your KRC's IP address on the network, and make sure kukaproxyvar is running.") 105 | self.disconnect() 106 | raise SystemExit 107 | elif ID == 2: 108 | print ("Python Error.") 109 | print ("Check the code and uncomment the lines related to your python version.") 110 | self.disconnect() 111 | raise SystemExit 112 | elif ID == 3: 113 | print ("Error in write() statement.") 114 | print ("Variable value is not defined.") 115 | 116 | if __name__ == "__main__": 117 | # Initialize OPC-UA Client connection 118 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 119 | 120 | # Setup robot object 121 | robot = KUKA('192.168.250.16') 122 | 123 | # Setup server 124 | server = Server() 125 | server.set_endpoint("opc.tcp://192.168.250.200:50895") 126 | 127 | # Setup namespace 128 | uri = "http://examples.freeopcua.github.io" 129 | idx = server.register_namespace(uri) 130 | 131 | # Get objects node 132 | objects = server.get_objects_node() 133 | 134 | # Populating address space 135 | myObject = objects.add_object(idx, "KUKA_KR16_2") 136 | 137 | # Adding desired variables 138 | A1 = myObject.add_variable(idx, "A1", 6.7) 139 | A2 = myObject.add_variable(idx, "A2", 6.7) 140 | A3 = myObject.add_variable(idx, "A3", 6.7) 141 | A4 = myObject.add_variable(idx, "A4", 6.7) 142 | A5 = myObject.add_variable(idx, "A5", 6.7) 143 | A6 = myObject.add_variable(idx, "A6", 6.7) 144 | 145 | A1.set_writable() 146 | A2.set_writable() 147 | A3.set_writable() 148 | A4.set_writable() 149 | A5.set_writable() 150 | A6.set_writable() 151 | 152 | # Starting OPC-UA Server 153 | server.start() 154 | 155 | # Values to be written 156 | values_A1 = [] 157 | values_A2 = [] 158 | values_A3 = [] 159 | values_A4 = [] 160 | values_A5 = [] 161 | values_A6 = [] 162 | 163 | try: 164 | # Timer for monitoring interval 165 | count = 0 166 | timer = 100 167 | offset = 273.15 # Kelvin to celcius 168 | 169 | while(count < timer): 170 | time.sleep(0.1) 171 | count+=1 172 | 173 | output = robot.read("$AXIS_ACT") 174 | output = output.replace(",", "") 175 | output_elements = output.split(" ") 176 | 177 | A1.set_value(output_elements[2]) 178 | A2.set_value(output_elements[4]) 179 | A3.set_value(output_elements[6]) 180 | A4.set_value(output_elements[8]) 181 | A5.set_value(output_elements[10]) 182 | A6.set_value(output_elements[12]) 183 | 184 | values_A1.append(float(robot.read("$MOT_TEMP [1]")) - offset) 185 | values_A2.append(float(robot.read("$MOT_TEMP [2]")) - offset) 186 | values_A3.append(float(robot.read("$MOT_TEMP [3]")) - offset) 187 | values_A4.append(float(robot.read("$MOT_TEMP [4]")) - offset) 188 | values_A5.append(float(robot.read("$MOT_TEMP [5]")) - offset) 189 | values_A6.append(float(robot.read("$MOT_TEMP [6]")) - offset) 190 | 191 | f = open('KUKA_KR16_2_motorTemp.csv', 'w') 192 | 193 | for i in range(0, len(values_A1)): 194 | f.write(str(values_A1[i]) + ",") 195 | f.write(str(values_A2[i]) + ",") 196 | f.write(str(values_A3[i]) + ",") 197 | f.write(str(values_A4[i]) + ",") 198 | f.write(str(values_A5[i]) + ",") 199 | f.write(str(values_A6[i]) + "\n") 200 | 201 | f.close() 202 | 203 | finally: 204 | #close connection, remove subcsriptions, etc 205 | server.stop() -------------------------------------------------------------------------------- /gui/server_gui_write_motorTorque.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Source code for an OPC UA server able to extract axis variables 3 | from a KUKA KR C4 robot controller and send them to an 4 | OPC UA client. The server also extracts information about the 5 | current torque on each of the motors controlling the different 6 | KUKA robot axis and writes the data to a .csv file called 7 | "KUKA_KR16_2_motorTorque.csv". 8 | 9 | Based on work by: 10 | - Massimiliano Fago (https://sourceforge.net/projects/openshowvar) 11 | - Mechatronics Lab at AAlesund University College 12 | (https://github.com/aauc-mechlab/JOpenShowVar) 13 | - Ahmad Saeed (https://github.com/akselov/kukavarproxy-msg-format) 14 | - Olivier Roulet-Dubonnet (https://github.com/FreeOpcUa) 15 | 16 | Author: Aksel Oevern 17 | NTNU 2018 18 | ''' 19 | 20 | import sys 21 | import socket 22 | sys.path.insert(0, "..") 23 | import time 24 | from opcua import ua, Server 25 | 26 | class KUKA(object): 27 | # Open socket 28 | # KukaVarProxy actively listens on TCP port 7000 29 | def __init__(self, TCP_IP): 30 | try: 31 | client.connect((TCP_IP, 7000)) 32 | except: 33 | self.error_list(1) 34 | 35 | # Sending messages on the KukaVarProxy message format: 36 | # Msg ID in HEX 2 bytes 37 | # Msg length in HEX 2 bytes 38 | # Read (0) or write (1) 1 byte 39 | # Variable name length in HEX 2 bytes 40 | # Variable name in ASCII # bytes 41 | # Variable value length in HEX 2 bytes 42 | # Variable value in ASCII # bytes 43 | def send (self, var, val, msgID): 44 | try: 45 | msg = bytearray() 46 | temp = bytearray() 47 | if val != "": 48 | val = str(val) 49 | msg.append((len(val) & 0xff00) >> 8) 50 | msg.append((len(val) & 0x00ff)) 51 | msg.extend(map(ord, val)) 52 | temp.append(bool(val)) 53 | temp.append(((len(var)) & 0xff00) >> 8) 54 | temp.append((len(var)) & 0x00ff) 55 | temp.extend(map(ord, var)) 56 | msg = temp + msg 57 | del temp[:] 58 | temp.append((msgID & 0xff00) >> 8) 59 | temp.append(msgID & 0x00ff) 60 | temp.append((len(msg) & 0xff00) >> 8) 61 | temp.append((len(msg) & 0x00ff)) 62 | msg = temp + msg 63 | except : 64 | self.error_list(2) 65 | try: 66 | client.send(msg) 67 | return client.recv(1024) 68 | except : 69 | self.error_list(1) 70 | 71 | # Get variables from KukaVarProxy response format 72 | def __get_var(self, msg): 73 | try: 74 | lsb = int( msg[5]) 75 | msb = int( msg[6]) 76 | lenValue = (lsb <<8 | msb) 77 | return str(msg [7: 7+lenValue],'utf-8') 78 | except: 79 | self.error_list(2) 80 | 81 | # Read variables from KukaVarProxy 82 | def read (self, var, msgID=0): 83 | try: 84 | return self.__get_var(self.send(var,"",msgID)) 85 | except : 86 | self.error_list(2) 87 | 88 | # Write variables to KukaVarProxy 89 | def write (self, var, val, msgID=0): 90 | try: 91 | if val != (""): return self.__get_var(self.send(var,val,msgID)) 92 | else: raise self.error_list(3) 93 | except : 94 | self.error_list(2) 95 | 96 | # Close socket 97 | def disconnect (self): 98 | client.close() 99 | 100 | # In case of error 101 | def error_list (self, ID): 102 | if ID == 1: 103 | print ("Network Error (tcp_error)") 104 | print ("Check your KRC's IP address on the network, and make sure kukaproxyvar is running.") 105 | self.disconnect() 106 | raise SystemExit 107 | elif ID == 2: 108 | print ("Python Error.") 109 | print ("Check the code and uncomment the lines related to your python version.") 110 | self.disconnect() 111 | raise SystemExit 112 | elif ID == 3: 113 | print ("Error in write() statement.") 114 | print ("Variable value is not defined.") 115 | 116 | if __name__ == "__main__": 117 | # Initialize OPC-UA Client connection 118 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 119 | 120 | # Setup robot object 121 | robot = KUKA('192.168.250.16') 122 | 123 | # Setup server 124 | server = Server() 125 | server.set_endpoint("opc.tcp://192.168.250.200:50895") 126 | 127 | # Setup namespace 128 | uri = "http://examples.freeopcua.github.io" 129 | idx = server.register_namespace(uri) 130 | 131 | # Get objects node 132 | objects = server.get_objects_node() 133 | 134 | # Populating address space 135 | myObject = objects.add_object(idx, "KUKA_KR16_2") 136 | 137 | # Adding desired variables 138 | A1 = myObject.add_variable(idx, "A1", 6.7) 139 | A2 = myObject.add_variable(idx, "A2", 6.7) 140 | A3 = myObject.add_variable(idx, "A3", 6.7) 141 | A4 = myObject.add_variable(idx, "A4", 6.7) 142 | A5 = myObject.add_variable(idx, "A5", 6.7) 143 | A6 = myObject.add_variable(idx, "A6", 6.7) 144 | 145 | A1.set_writable() 146 | A2.set_writable() 147 | A3.set_writable() 148 | A4.set_writable() 149 | A5.set_writable() 150 | A6.set_writable() 151 | 152 | # Starting OPC-UA Server 153 | server.start() 154 | 155 | # Values to be written 156 | values_A1 = [] 157 | values_A2 = [] 158 | values_A3 = [] 159 | values_A4 = [] 160 | values_A5 = [] 161 | values_A6 = [] 162 | 163 | try: 164 | # Timer for monitoring interval 165 | count = 0 166 | timer = 100 167 | while(count < timer): 168 | time.sleep(0.1) 169 | count+=1 170 | 171 | output = robot.read("$AXIS_ACT") 172 | output = output.replace(",", "") 173 | output_elements = output.split(" ") 174 | 175 | A1.set_value(output_elements[2]) 176 | A2.set_value(output_elements[4]) 177 | A3.set_value(output_elements[6]) 178 | A4.set_value(output_elements[8]) 179 | A5.set_value(output_elements[10]) 180 | A6.set_value(output_elements[12]) 181 | 182 | values_A1.append(float(robot.read("$TORQUE_AXIS_ACT [1]"))) 183 | values_A2.append(float(robot.read("$TORQUE_AXIS_ACT [2]"))) 184 | values_A3.append(float(robot.read("$TORQUE_AXIS_ACT [3]"))) 185 | values_A4.append(float(robot.read("$TORQUE_AXIS_ACT [4]"))) 186 | values_A5.append(float(robot.read("$TORQUE_AXIS_ACT [5]"))) 187 | values_A6.append(float(robot.read("$TORQUE_AXIS_ACT [6]"))) 188 | 189 | f = open('KUKA_KR16_2_motorTorque.csv', 'w') 190 | 191 | for i in range(0, len(values_A1)): 192 | f.write(str(values_A1[i]) + ",") 193 | f.write(str(values_A2[i]) + ",") 194 | f.write(str(values_A3[i]) + ",") 195 | f.write(str(values_A4[i]) + ",") 196 | f.write(str(values_A5[i]) + ",") 197 | f.write(str(values_A6[i]) + "\n") 198 | 199 | f.close() 200 | 201 | finally: 202 | # Close OPC UA client connection, remove subcsriptions, etc 203 | server.stop() -------------------------------------------------------------------------------- /opcua-control/opcua-control-server.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Source code for an OPC UA server able to create a custom OPC UA 3 | object from specifications in a XML-file, extract axis variables 4 | from an OPC UA client and control a KUKA robot by its axis values. 5 | 6 | Based on work by: 7 | - Massimiliano Fago (https://sourceforge.net/projects/openshowvar) 8 | - Mechatronics Lab at AAlesund University College 9 | (https://github.com/aauc-mechlab/JOpenShowVar) 10 | - Ahmad Saeed (https://github.com/akselov/kukavarproxy-msg-format) 11 | - Olivier Roulet-Dubonnet (https://github.com/FreeOpcUa) 12 | 13 | To be done: 14 | - Custom setup of axis variables from OPC UA object 15 | - Include RSI control module 16 | 17 | Author: Aksel Oevern 18 | NTNU 2018 19 | ''' 20 | 21 | import sys 22 | import socket 23 | sys.path.insert(0, "..") 24 | import time 25 | from xml.dom import minidom 26 | from opcua import ua, Server 27 | 28 | class KUKA(object): 29 | # Open socket 30 | # KukaVarProxy actively listens on TCP port 7000 31 | def __init__(self, TCP_IP): 32 | try: 33 | client.connect((TCP_IP, 7000)) 34 | except: 35 | self.error_list(1) 36 | 37 | # Sending messages on the KukaVarProxy message format: 38 | # Msg ID in HEX 2 bytes 39 | # Msg length in HEX 2 bytes 40 | # Read (0) or write (1) 1 byte 41 | # Variable name length in HEX 2 bytes 42 | # Variable name in ASCII # bytes 43 | # Variable value length in HEX 2 bytes 44 | # Variable value in ASCII # bytes 45 | def send (self, var, val, msgID): 46 | try: 47 | msg = bytearray() 48 | temp = bytearray() 49 | if val != "": 50 | val = str(val) 51 | msg.append((len(val) & 0xff00) >> 8) 52 | msg.append((len(val) & 0x00ff)) 53 | msg.extend(map(ord, val)) 54 | temp.append(bool(val)) 55 | temp.append(((len(var)) & 0xff00) >> 8) 56 | temp.append((len(var)) & 0x00ff) 57 | temp.extend(map(ord, var)) 58 | msg = temp + msg 59 | del temp[:] 60 | temp.append((msgID & 0xff00) >> 8) 61 | temp.append(msgID & 0x00ff) 62 | temp.append((len(msg) & 0xff00) >> 8) 63 | temp.append((len(msg) & 0x00ff)) 64 | msg = temp + msg 65 | except : 66 | self.error_list(2) 67 | try: 68 | client.send(msg) 69 | return client.recv(1024) 70 | except : 71 | self.error_list(1) 72 | 73 | # Get variables from KukaVarProxy response format 74 | def __get_var(self, msg): 75 | try: 76 | lsb = int( msg[5]) 77 | msb = int( msg[6]) 78 | lenValue = (lsb <<8 | msb) 79 | return str(msg [7: 7+lenValue],'utf-8') 80 | except: 81 | self.error_list(2) 82 | 83 | # Read variables from KukaVarProxy 84 | def read (self, var, msgID=0): 85 | try: 86 | return self.__get_var(self.send(var,"",msgID)) 87 | except : 88 | self.error_list(2) 89 | 90 | # Write variables to KukaVarProxy 91 | def write (self, var, val, msgID=0): 92 | try: 93 | if val != (""): 94 | return self.__get_var(self.send(var,val,msgID)) 95 | else: 96 | raise self.error_list(3) 97 | except : 98 | self.error_list(2) 99 | 100 | # Close socket 101 | def disconnect (self): 102 | client.close() 103 | 104 | # In case of error 105 | def error_list (self, ID): 106 | if ID == 1: 107 | print ("Network Error (tcp_error)") 108 | print ("Check your KRC's IP address on the network, and make sure kukaproxyvar is running.") 109 | self.disconnect() 110 | raise SystemExit 111 | elif ID == 2: 112 | print ("Python Error.") 113 | print ("Check the code and uncomment the lines related to your python version.") 114 | self.disconnect() 115 | raise SystemExit 116 | elif ID == 3: 117 | print ("Error in write() statement.") 118 | print ("Variable value is not defined.") 119 | 120 | 121 | if __name__ == "__main__": 122 | # Initialize OPC-UA Client connection 123 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 124 | 125 | # Setup robot object 126 | robot = KUKA('192.168.250.16') 127 | 128 | # Setup OPC-UA Server 129 | server = Server() 130 | server.set_endpoint("opc.tcp://192.168.250.200:50895") 131 | 132 | # Setup namespace 133 | uri = "http://examples.freeopcua.github.io" 134 | idx = server.register_namespace(uri) 135 | 136 | # Get objects node 137 | objects = server.get_objects_node() 138 | 139 | # Import customobject type 140 | server.import_xml('KUKA_KR16_2_object.xml') 141 | 142 | # Check if client wants communication over KUKAVARPROXY or RSI 143 | kuka_object = objects.get_child("0:KUKA_KR16_2") 144 | variable_kukavarproxy = kuka_object.get_child("0:KUKAVARPROXY") 145 | variable_rsi = kuka_object.get_child("0:RSI") 146 | 147 | # Manual setup of axis variables for OPC UA object 148 | A1_var = kuka_object.get_child("0:A1") 149 | A2_var = kuka_object.get_child("0:A2") 150 | A3_var = kuka_object.get_child("0:A3") 151 | A4_var = kuka_object.get_child("0:A4") 152 | A5_var = kuka_object.get_child("0:A5") 153 | A6_var = kuka_object.get_child("0:A6") 154 | 155 | # Make KVP and RSI configuration writable by OPC UA client 156 | variable_kukavarproxy.set_writable() 157 | variable_rsi.set_writable() 158 | 159 | # Extracting axis variables and removing KUKAVARPROXU/RSI configuration variables 160 | variables_all = kuka_object.get_children() 161 | variables_all.remove(variable_kukavarproxy) 162 | variables_all.remove(variable_rsi) 163 | variables_axis = variables_all 164 | 165 | for variable_axis in variables_axis: 166 | variable_axis.set_writable() 167 | 168 | # Starting OPC-UA Server 169 | server.start() 170 | 171 | try: 172 | # Give user information about communication that is being used 173 | print("Kuka: ", variable_kukavarproxy.get_value()) 174 | print("RSI: ", variable_rsi.get_value()) 175 | print("Select KUKAVARPROXY or RSI control configuration in OPC UA Client") 176 | 177 | while True: 178 | time.sleep(0.1) 179 | 180 | # Check for client preference KUKAVARPROXY/RSI control 181 | if(variable_kukavarproxy.get_value() and variable_rsi.get_value()): 182 | raise ValueError("KUKAVARPROXY and RSI can not both be selected") 183 | SystemExit 184 | 185 | if(variable_kukavarproxy.get_value()): 186 | print("Launching KUKAVARPROXY control") 187 | robot.write("TARGET_AXIS","{E6AXIS: A1 " + str(A1_var.get_value()) + ", A2 " + str(A2_var.get_value()) + ", A3 " + str(A3_var.get_value()) + ", A4 " + str(A4_var.get_value()) + ", A5 " + str(A5_var.get_value()) + ", A6 " + str(A6_var.get_value()) + "}") 188 | 189 | if(variable_rsi.get_value()): 190 | print("Launching RSI control") 191 | #Run RSI control module 192 | 193 | finally: 194 | # Close OPC UA client connection, remove subcsriptions, etc 195 | server.stop() 196 | -------------------------------------------------------------------------------- /opcua-control/opcua_ptp_movement.dat: -------------------------------------------------------------------------------- 1 | &ACCESS RVP 2 | &REL 31 3 | &PARAM TEMPLATE = C:\KRC\Roboter\Template\vorgabe 4 | &PARAM EDITMASK = * 5 | DEFDAT opcua_ptp_movement PUBLIC 6 | ;FOLD EXTERNAL DECLARATIONS;%{PE}%MKUKATPBASIS,%CEXT,%VCOMMON,%P 7 | ;FOLD BASISTECH EXT;%{PE}%MKUKATPBASIS,%CEXT,%VEXT,%P 8 | EXT BAS (BAS_COMMAND :IN,REAL :IN ) 9 | DECL INT SUCCESS 10 | ;ENDFOLD (BASISTECH EXT) 11 | ;FOLD USER EXT;%{E}%MKUKATPUSER,%CEXT,%VEXT,%P 12 | ;Make your modifications here 13 | 14 | ;ENDFOLD (USER EXT) 15 | ;ENDFOLD (EXTERNAL DECLARATIONS) 16 | 17 | DECL GLOBAL E6AXIS TARGET_AXIS 18 | DECL GLOBAL BOOL YUFI=TRUE 19 | DECL BASIS_SUGG_T LAST_BASIS={POINT1[] "P0 ",POINT2[] "P0 ",CP_PARAMS[] "CPDAT0 ",PTP_PARAMS[] "PDAT0 ",CONT[] " ",CP_VEL[] "2.0 ",PTP_VEL[] " 100 ",SYNC_PARAMS[] "SYNCDAT ",SPL_NAME[] "S0 "} 20 | ENDDAT 21 | -------------------------------------------------------------------------------- /opcua-control/opcua_ptp_movement.src: -------------------------------------------------------------------------------- 1 | &ACCESS RVP 2 | &REL 31 3 | &PARAM TEMPLATE = C:\KRC\Roboter\Template\vorgabe 4 | &PARAM EDITMASK = * 5 | DEF opcua_ptp_movement( ) 6 | 7 | ;FOLD INI;%{PE} 8 | ;FOLD BASISTECH INI 9 | GLOBAL INTERRUPT DECL 3 WHEN $STOPMESS==TRUE DO IR_STOPM ( ) 10 | INTERRUPT ON 3 11 | BAS (#INITMOV,0 ) 12 | ;ENDFOLD (BASISTECH INI) 13 | ;FOLD USER INI 14 | ;Make your modifications here 15 | 16 | ;ENDFOLD (USER INI) 17 | ;ENDFOLD (INI) 18 | 19 | ;FOLD PTP HOME Vel= 100 % DEFAULT;%{PE}%MKUKATPBASIS,%CMOVE,%VPTP,%P 1:PTP, 2:HOME, 3:, 5:100, 7:DEFAULT 20 | $BWDSTART = FALSE 21 | PDAT_ACT=PDEFAULT 22 | FDAT_ACT=FHOME 23 | BAS (#PTP_PARAMS,100 ) 24 | $H_POS=XHOME 25 | PTP XHOME 26 | ;ENDFOLD 27 | TARGET_AXIS = $AXIS_ACT; 28 | 29 | LOOP 30 | PTP TARGET_AXIS 31 | ENDLOOP 32 | END 33 | -------------------------------------------------------------------------------- /opcua-server/opcua-server-current-to-file.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Source code for an OPC UA server able to extract axis variables 3 | from a KUKA KR C4 robot controller and send them to an 4 | OPC UA client. The server also extracts information about the 5 | current of each of the motors controlling the different 6 | KUKA robot axis and writes the data to a .csv file called 7 | "KUKA_KR16_2_motorCurrent.csv". 8 | 9 | Based on work by: 10 | - Massimiliano Fago (https://sourceforge.net/projects/openshowvar) 11 | - Mechatronics Lab at AAlesund University College 12 | (https://github.com/aauc-mechlab/JOpenShowVar) 13 | - Ahmad Saeed (https://github.com/akselov/kukavarproxy-msg-format) 14 | - Olivier Roulet-Dubonnet (https://github.com/FreeOpcUa) 15 | 16 | Author: Aksel Oevern 17 | NTNU 2018 18 | ''' 19 | 20 | import sys 21 | import socket 22 | sys.path.insert(0, "..") 23 | import time 24 | from opcua import ua, Server 25 | 26 | class KUKA(object): 27 | # Open socket 28 | # KukaVarProxy actively listens on TCP port 7000 29 | def __init__(self, TCP_IP): 30 | try: 31 | client.connect((TCP_IP, 7000)) 32 | except: 33 | self.error_list(1) 34 | 35 | # Sending messages on the KukaVarProxy message format: 36 | # Msg ID in HEX 2 bytes 37 | # Msg length in HEX 2 bytes 38 | # Read (0) or write (1) 1 byte 39 | # Variable name length in HEX 2 bytes 40 | # Variable name in ASCII # bytes 41 | # Variable value length in HEX 2 bytes 42 | # Variable value in ASCII # bytes 43 | def send (self, var, val, msgID): 44 | try: 45 | msg = bytearray() 46 | temp = bytearray() 47 | if val != "": 48 | val = str(val) 49 | msg.append((len(val) & 0xff00) >> 8) 50 | msg.append((len(val) & 0x00ff)) 51 | msg.extend(map(ord, val)) 52 | temp.append(bool(val)) 53 | temp.append(((len(var)) & 0xff00) >> 8) 54 | temp.append((len(var)) & 0x00ff) 55 | temp.extend(map(ord, var)) 56 | msg = temp + msg 57 | del temp[:] 58 | temp.append((msgID & 0xff00) >> 8) 59 | temp.append(msgID & 0x00ff) 60 | temp.append((len(msg) & 0xff00) >> 8) 61 | temp.append((len(msg) & 0x00ff)) 62 | msg = temp + msg 63 | except : 64 | self.error_list(2) 65 | try: 66 | client.send(msg) 67 | return client.recv(1024) 68 | except : 69 | self.error_list(1) 70 | 71 | # Get variables from KukaVarProxy response format 72 | def __get_var(self, msg): 73 | try: 74 | lsb = int( msg[5]) 75 | msb = int( msg[6]) 76 | lenValue = (lsb <<8 | msb) 77 | return str(msg [7: 7+lenValue],'utf-8') 78 | except: 79 | self.error_list(2) 80 | 81 | # Read variables from KukaVarProxy 82 | def read (self, var, msgID=0): 83 | try: 84 | return self.__get_var(self.send(var,"",msgID)) 85 | except : 86 | self.error_list(2) 87 | 88 | # Write variables to KukaVarProxy 89 | def write (self, var, val, msgID=0): 90 | try: 91 | if val != (""): return self.__get_var(self.send(var,val,msgID)) 92 | else: raise self.error_list(3) 93 | except : 94 | self.error_list(2) 95 | 96 | # Close socket 97 | def disconnect (self): 98 | client.close() 99 | 100 | # In case of error 101 | def error_list (self, ID): 102 | if ID == 1: 103 | print ("Network Error (tcp_error)") 104 | print ("Check your KRC's IP address on the network, and make sure kukaproxyvar is running.") 105 | self.disconnect() 106 | raise SystemExit 107 | elif ID == 2: 108 | print ("Python Error.") 109 | print ("Check the code and uncomment the lines related to your python version.") 110 | self.disconnect() 111 | raise SystemExit 112 | elif ID == 3: 113 | print ("Error in write() statement.") 114 | print ("Variable value is not defined.") 115 | 116 | if __name__ == "__main__": 117 | # Initialize OPC-UA Client connection 118 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 119 | 120 | # Setup robot object 121 | robot = KUKA('192.168.250.16') 122 | 123 | # Setup server 124 | server = Server() 125 | server.set_endpoint("opc.tcp://192.168.250.200:50895") 126 | 127 | # Setup namespace 128 | uri = "http://examples.freeopcua.github.io" 129 | idx = server.register_namespace(uri) 130 | 131 | # Get objects node 132 | objects = server.get_objects_node() 133 | 134 | # Populating address space 135 | myObject = objects.add_object(idx, "KUKA_KR16_2") 136 | 137 | # Adding desired variables 138 | A1 = myObject.add_variable(idx, "A1", 6.7) 139 | A2 = myObject.add_variable(idx, "A2", 6.7) 140 | A3 = myObject.add_variable(idx, "A3", 6.7) 141 | A4 = myObject.add_variable(idx, "A4", 6.7) 142 | A5 = myObject.add_variable(idx, "A5", 6.7) 143 | A6 = myObject.add_variable(idx, "A6", 6.7) 144 | 145 | A1.set_writable() 146 | A2.set_writable() 147 | A3.set_writable() 148 | A4.set_writable() 149 | A5.set_writable() 150 | A6.set_writable() 151 | 152 | # Starting OPC-UA Server 153 | server.start() 154 | 155 | # Values to be written 156 | values_A1 = [] 157 | values_A2 = [] 158 | values_A3 = [] 159 | values_A4 = [] 160 | values_A5 = [] 161 | values_A6 = [] 162 | 163 | try: 164 | # Timer for monitoring interval 165 | count = 0 166 | timer = 100 167 | while(count < timer): 168 | time.sleep(0.1) 169 | count+=1 170 | 171 | output = robot.read("$AXIS_ACT") 172 | output = output.replace(",", "") 173 | output_elements = output.split(" ") 174 | 175 | A1.set_value(output_elements[2]) 176 | A2.set_value(output_elements[4]) 177 | A3.set_value(output_elements[6]) 178 | A4.set_value(output_elements[8]) 179 | A5.set_value(output_elements[10]) 180 | A6.set_value(output_elements[12]) 181 | 182 | values_A1.append(float(robot.read("$CURR_ACT [1]"))) 183 | values_A2.append(float(robot.read("$CURR_ACT [2]"))) 184 | values_A3.append(float(robot.read("$CURR_ACT [3]"))) 185 | values_A4.append(float(robot.read("$CURR_ACT [4]"))) 186 | values_A5.append(float(robot.read("$CURR_ACT [5]"))) 187 | values_A6.append(float(robot.read("$CURR_ACT [6]"))) 188 | 189 | f = open('KUKA_KR16_2_motorCurrent.csv', 'w') 190 | 191 | for i in range(0, len(values_A1)): 192 | f.write(str(values_A1[i]) + ",") 193 | f.write(str(values_A2[i]) + ",") 194 | f.write(str(values_A3[i]) + ",") 195 | f.write(str(values_A4[i]) + ",") 196 | f.write(str(values_A5[i]) + ",") 197 | f.write(str(values_A6[i]) + "\n") 198 | 199 | f.close() 200 | 201 | finally: 202 | # Close OPC UA client connection, remove subcsriptions, etc 203 | server.stop() -------------------------------------------------------------------------------- /opcua-server/opcua-server-current.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Source code for an OPC UA server able to extract axis variables 3 | from a KUKA KR C4 robot controller and send them to an 4 | OPC UA client. The server also extracts information about the 5 | current going into each of the motors controlling the different 6 | KUKA robot axis and does a real-time plot of all the values. 7 | 8 | Based on work by: 9 | - Massimiliano Fago (https://sourceforge.net/projects/openshowvar) 10 | - Mechatronics Lab at AAlesund University College 11 | (https://github.com/aauc-mechlab/JOpenShowVar) 12 | - Ahmad Saeed (https://github.com/akselov/kukavarproxy-msg-format) 13 | - Olivier Roulet-Dubonnet (https://github.com/FreeOpcUa) 14 | 15 | Author: Aksel Oevern 16 | NTNU 2018 17 | ''' 18 | 19 | import sys 20 | import socket 21 | sys.path.insert(0, "..") 22 | import time 23 | import numpy as np 24 | import matplotlib.pyplot as plt 25 | from opcua import ua, Server 26 | 27 | class KUKA(object): 28 | # Open socket 29 | # KukaVarProxy actively listens on TCP port 7000 30 | def __init__(self, TCP_IP): 31 | try: 32 | client.connect((TCP_IP, 7000)) 33 | except: 34 | self.error_list(1) 35 | 36 | # Sending messages on the KukaVarProxy message format: 37 | # Msg ID in HEX 2 bytes 38 | # Msg length in HEX 2 bytes 39 | # Read (0) or write (1) 1 byte 40 | # Variable name length in HEX 2 bytes 41 | # Variable name in ASCII # bytes 42 | # Variable value length in HEX 2 bytes 43 | # Variable value in ASCII # bytes 44 | def send (self, var, val, msgID): 45 | try: 46 | msg = bytearray() 47 | temp = bytearray() 48 | if val != "": 49 | val = str(val) 50 | msg.append((len(val) & 0xff00) >> 8) 51 | msg.append((len(val) & 0x00ff)) 52 | msg.extend(map(ord, val)) 53 | temp.append(bool(val)) 54 | temp.append(((len(var)) & 0xff00) >> 8) 55 | temp.append((len(var)) & 0x00ff) 56 | temp.extend(map(ord, var)) 57 | msg = temp + msg 58 | del temp[:] 59 | temp.append((msgID & 0xff00) >> 8) 60 | temp.append(msgID & 0x00ff) 61 | temp.append((len(msg) & 0xff00) >> 8) 62 | temp.append((len(msg) & 0x00ff)) 63 | msg = temp + msg 64 | except : 65 | self.error_list(2) 66 | try: 67 | client.send(msg) 68 | return client.recv(1024) 69 | except : 70 | self.error_list(1) 71 | 72 | # Get variables from KukaVarProxy response format 73 | def __get_var(self, msg): 74 | try: 75 | lsb = int( msg[5]) 76 | msb = int( msg[6]) 77 | lenValue = (lsb <<8 | msb) 78 | return str(msg [7: 7+lenValue],'utf-8') 79 | except: 80 | self.error_list(2) 81 | 82 | # Read variables from KukaVarProxy 83 | def read (self, var, msgID=0): 84 | try: 85 | return self.__get_var(self.send(var,"",msgID)) 86 | except : 87 | self.error_list(2) 88 | 89 | # Write variables to KukaVarProxy 90 | def write (self, var, val, msgID=0): 91 | try: 92 | if val != (""): return self.__get_var(self.send(var,val,msgID)) 93 | else: raise self.error_list(3) 94 | except : 95 | self.error_list(2) 96 | 97 | # Close socket 98 | def disconnect (self): 99 | client.close() 100 | 101 | # In case of error 102 | def error_list (self, ID): 103 | if ID == 1: 104 | print ("Network Error (tcp_error)") 105 | print ("Check your KRC's IP address on the network, and make sure kukaproxyvar is running.") 106 | self.disconnect() 107 | raise SystemExit 108 | elif ID == 2: 109 | print ("Python Error.") 110 | print ("Check the code and uncomment the lines related to your python version.") 111 | self.disconnect() 112 | raise SystemExit 113 | elif ID == 3: 114 | print ("Error in write() statement.") 115 | print ("Variable value is not defined.") 116 | 117 | if __name__ == "__main__": 118 | # Initialize OPC-UA Client connection 119 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 120 | 121 | # Setup robot object 122 | robot = KUKA('192.168.250.16') 123 | 124 | # Setup server 125 | server = Server() 126 | server.set_endpoint("opc.tcp://192.168.250.200:50895") 127 | 128 | # Setup namespace 129 | uri = "http://examples.freeopcua.github.io" 130 | idx = server.register_namespace(uri) 131 | 132 | # Get objects node 133 | objects = server.get_objects_node() 134 | 135 | # Populating address space 136 | myObject = objects.add_object(idx, "KUKA_KR16_2") 137 | 138 | # Adding desired variables 139 | A1 = myObject.add_variable(idx, "A1", 6.7) 140 | A2 = myObject.add_variable(idx, "A2", 6.7) 141 | A3 = myObject.add_variable(idx, "A3", 6.7) 142 | A4 = myObject.add_variable(idx, "A4", 6.7) 143 | A5 = myObject.add_variable(idx, "A5", 6.7) 144 | A6 = myObject.add_variable(idx, "A6", 6.7) 145 | 146 | A1.set_writable() 147 | A2.set_writable() 148 | A3.set_writable() 149 | A4.set_writable() 150 | A5.set_writable() 151 | A6.set_writable() 152 | 153 | # Starting OPC-UA Server 154 | server.start() 155 | 156 | # Start plot 157 | xaxis_t0 = 100 158 | plt.axis([0, xaxis_t0, -100, 100]) 159 | plt.title('Actual Current of Axes KUKA KR 16-2, Axis 1-6') 160 | plt.grid(True) 161 | plt.xlabel('time [s*10]') 162 | plt.ylabel('Current [%]') 163 | plt.ion() 164 | count = 0 165 | 166 | plotted_values_A1 = [] 167 | plotted_values_A2 = [] 168 | plotted_values_A3 = [] 169 | plotted_values_A4 = [] 170 | plotted_values_A5 = [] 171 | plotted_values_A6 = [] 172 | 173 | plt.plot(plotted_values_A1, 'b', label='Axis 1') 174 | plt.plot(plotted_values_A2, 'r', label='Axis 2') 175 | plt.plot(plotted_values_A3, 'g', label='Axis 3') 176 | plt.plot(plotted_values_A4, 'c', label='Axis 4') 177 | plt.plot(plotted_values_A5, 'm', label='Axis 5') 178 | plt.plot(plotted_values_A6, 'y', label='Axis 6') 179 | 180 | plt.legend() 181 | 182 | try: 183 | count = 0 184 | while True: 185 | time.sleep(0.1) 186 | 187 | output = robot.read("$AXIS_ACT") 188 | output = output.replace(",", "") 189 | output_elements = output.split(" ") 190 | 191 | A1.set_value(output_elements[2]) 192 | A2.set_value(output_elements[4]) 193 | A3.set_value(output_elements[6]) 194 | A4.set_value(output_elements[8]) 195 | A5.set_value(output_elements[10]) 196 | A6.set_value(output_elements[12]) 197 | 198 | plotted_values_A1.append(float(robot.read("$CURR_ACT [1]"))) 199 | plotted_values_A2.append(float(robot.read("$CURR_ACT [2]"))) 200 | plotted_values_A3.append(float(robot.read("$CURR_ACT [3]"))) 201 | plotted_values_A4.append(float(robot.read("$CURR_ACT [4]"))) 202 | plotted_values_A5.append(float(robot.read("$CURR_ACT [5]"))) 203 | plotted_values_A6.append(float(robot.read("$CURR_ACT [6]"))) 204 | 205 | plt.plot(plotted_values_A1, 'b', label='Axis 1') 206 | plt.plot(plotted_values_A2, 'r', label='Axis 2') 207 | plt.plot(plotted_values_A3, 'g', label='Axis 3') 208 | plt.plot(plotted_values_A4, 'c', label='Axis 4') 209 | plt.plot(plotted_values_A5, 'm', label='Axis 5') 210 | plt.plot(plotted_values_A6, 'y', label='Axis 6') 211 | 212 | plt.pause(0.00001) 213 | count+=1 214 | 215 | # Resizing plot 216 | if(count+20 > xaxis_t0): 217 | xaxis_t0+=50 218 | plt.axis([0, xaxis_t0, -100, 100]) 219 | 220 | finally: 221 | # Close OPC UA client connection, remove subcsriptions, etc 222 | server.stop() -------------------------------------------------------------------------------- /opcua-server/opcua-server-temperature-to-file.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Source code for an OPC UA server able to extract axis variables 3 | from a KUKA KR C4 robot controller and send them to an 4 | OPC UA client. The server also extracts information about the 5 | current temperature of each of the motors controlling the different 6 | KUKA robot axis and writes the data to a .csv file called 7 | "KUKA_KR16_2_motorTemp.csv". 8 | 9 | Based on work by: 10 | - Massimiliano Fago (https://sourceforge.net/projects/openshowvar) 11 | - Mechatronics Lab at AAlesund University College 12 | (https://github.com/aauc-mechlab/JOpenShowVar) 13 | - Ahmad Saeed (https://github.com/akselov/kukavarproxy-msg-format) 14 | - Olivier Roulet-Dubonnet (https://github.com/FreeOpcUa) 15 | 16 | Author: Aksel Oevern 17 | NTNU 2018 18 | ''' 19 | 20 | import sys 21 | import socket 22 | sys.path.insert(0, "..") 23 | import time 24 | from opcua import ua, Server 25 | 26 | class KUKA(object): 27 | # Open socket 28 | # KukaVarProxy actively listens on TCP port 7000 29 | def __init__(self, TCP_IP): 30 | try: 31 | client.connect((TCP_IP, 7000)) 32 | except: 33 | self.error_list(1) 34 | 35 | # Sending messages on the KukaVarProxy message format: 36 | # Msg ID in HEX 2 bytes 37 | # Msg length in HEX 2 bytes 38 | # Read (0) or write (1) 1 byte 39 | # Variable name length in HEX 2 bytes 40 | # Variable name in ASCII # bytes 41 | # Variable value length in HEX 2 bytes 42 | # Variable value in ASCII # bytes 43 | def send (self, var, val, msgID): 44 | try: 45 | msg = bytearray() 46 | temp = bytearray() 47 | if val != "": 48 | val = str(val) 49 | msg.append((len(val) & 0xff00) >> 8) 50 | msg.append((len(val) & 0x00ff)) 51 | msg.extend(map(ord, val)) 52 | temp.append(bool(val)) 53 | temp.append(((len(var)) & 0xff00) >> 8) 54 | temp.append((len(var)) & 0x00ff) 55 | temp.extend(map(ord, var)) 56 | msg = temp + msg 57 | del temp[:] 58 | temp.append((msgID & 0xff00) >> 8) 59 | temp.append(msgID & 0x00ff) 60 | temp.append((len(msg) & 0xff00) >> 8) 61 | temp.append((len(msg) & 0x00ff)) 62 | msg = temp + msg 63 | except : 64 | self.error_list(2) 65 | try: 66 | client.send(msg) 67 | return client.recv(1024) 68 | except : 69 | self.error_list(1) 70 | 71 | # Get variables from KukaVarProxy response format 72 | def __get_var(self, msg): 73 | try: 74 | lsb = int( msg[5]) 75 | msb = int( msg[6]) 76 | lenValue = (lsb <<8 | msb) 77 | return str(msg [7: 7+lenValue],'utf-8') 78 | except: 79 | self.error_list(2) 80 | 81 | # Read variables from KukaVarProxy 82 | def read (self, var, msgID=0): 83 | try: 84 | return self.__get_var(self.send(var,"",msgID)) 85 | except : 86 | self.error_list(2) 87 | 88 | # Write variables to KukaVarProxy 89 | def write (self, var, val, msgID=0): 90 | try: 91 | if val != (""): return self.__get_var(self.send(var,val,msgID)) 92 | else: raise self.error_list(3) 93 | except : 94 | self.error_list(2) 95 | 96 | # Close socket 97 | def disconnect (self): 98 | client.close() 99 | 100 | # In case of error 101 | def error_list (self, ID): 102 | if ID == 1: 103 | print ("Network Error (tcp_error)") 104 | print ("Check your KRC's IP address on the network, and make sure kukaproxyvar is running.") 105 | self.disconnect() 106 | raise SystemExit 107 | elif ID == 2: 108 | print ("Python Error.") 109 | print ("Check the code and uncomment the lines related to your python version.") 110 | self.disconnect() 111 | raise SystemExit 112 | elif ID == 3: 113 | print ("Error in write() statement.") 114 | print ("Variable value is not defined.") 115 | 116 | if __name__ == "__main__": 117 | # Initialize OPC-UA Client connection 118 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 119 | 120 | # Setup robot object 121 | robot = KUKA('192.168.250.16') 122 | 123 | # Setup server 124 | server = Server() 125 | server.set_endpoint("opc.tcp://192.168.250.200:50895") 126 | 127 | # Setup namespace 128 | uri = "http://examples.freeopcua.github.io" 129 | idx = server.register_namespace(uri) 130 | 131 | # Get objects node 132 | objects = server.get_objects_node() 133 | 134 | # Populating address space 135 | myObject = objects.add_object(idx, "KUKA_KR16_2") 136 | 137 | # Adding desired variables 138 | A1 = myObject.add_variable(idx, "A1", 6.7) 139 | A2 = myObject.add_variable(idx, "A2", 6.7) 140 | A3 = myObject.add_variable(idx, "A3", 6.7) 141 | A4 = myObject.add_variable(idx, "A4", 6.7) 142 | A5 = myObject.add_variable(idx, "A5", 6.7) 143 | A6 = myObject.add_variable(idx, "A6", 6.7) 144 | 145 | A1.set_writable() 146 | A2.set_writable() 147 | A3.set_writable() 148 | A4.set_writable() 149 | A5.set_writable() 150 | A6.set_writable() 151 | 152 | # Starting OPC-UA Server 153 | server.start() 154 | 155 | # Values to be written 156 | values_A1 = [] 157 | values_A2 = [] 158 | values_A3 = [] 159 | values_A4 = [] 160 | values_A5 = [] 161 | values_A6 = [] 162 | 163 | try: 164 | # Timer for monitoring interval 165 | count = 0 166 | timer = 100 167 | offset = 273.15 # Kelvin to celcius 168 | 169 | while(count < timer): 170 | time.sleep(0.1) 171 | count+=1 172 | 173 | output = robot.read("$AXIS_ACT") 174 | output = output.replace(",", "") 175 | output_elements = output.split(" ") 176 | 177 | A1.set_value(output_elements[2]) 178 | A2.set_value(output_elements[4]) 179 | A3.set_value(output_elements[6]) 180 | A4.set_value(output_elements[8]) 181 | A5.set_value(output_elements[10]) 182 | A6.set_value(output_elements[12]) 183 | 184 | values_A1.append(float(robot.read("$MOT_TEMP [1]")) - offset) 185 | values_A2.append(float(robot.read("$MOT_TEMP [2]")) - offset) 186 | values_A3.append(float(robot.read("$MOT_TEMP [3]")) - offset) 187 | values_A4.append(float(robot.read("$MOT_TEMP [4]")) - offset) 188 | values_A5.append(float(robot.read("$MOT_TEMP [5]")) - offset) 189 | values_A6.append(float(robot.read("$MOT_TEMP [6]")) - offset) 190 | 191 | f = open('KUKA_KR16_2_motorTemp.csv', 'w') 192 | 193 | for i in range(0, len(values_A1)): 194 | f.write(str(values_A1[i]) + ",") 195 | f.write(str(values_A2[i]) + ",") 196 | f.write(str(values_A3[i]) + ",") 197 | f.write(str(values_A4[i]) + ",") 198 | f.write(str(values_A5[i]) + ",") 199 | f.write(str(values_A6[i]) + "\n") 200 | 201 | f.close() 202 | 203 | finally: 204 | #close connection, remove subcsriptions, etc 205 | server.stop() -------------------------------------------------------------------------------- /opcua-server/opcua-server-temperature.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Source code for an OPC UA server able to extract axis variables 3 | from a KUKA KR C4 robot controller and send them to an 4 | OPC UA client. The server also extracts information about the 5 | current velocity of each of the motors controlling the different 6 | KUKA robot axis and does a real-time plot of all the values. 7 | 8 | Based on work by: 9 | - Massimiliano Fago (https://sourceforge.net/projects/openshowvar) 10 | - Mechatronics Lab at AAlesund University College 11 | (https://github.com/aauc-mechlab/JOpenShowVar) 12 | - Ahmad Saeed (https://github.com/akselov/kukavarproxy-msg-format) 13 | - Olivier Roulet-Dubonnet (https://github.com/FreeOpcUa) 14 | 15 | Author: Aksel Oevern 16 | NTNU 2018 17 | ''' 18 | 19 | import sys 20 | import socket 21 | sys.path.insert(0, "..") 22 | import time 23 | import numpy as np 24 | import matplotlib.pyplot as plt 25 | import matplotlib.colors as clr 26 | from opcua import ua, Server 27 | 28 | class KUKA(object): 29 | # Open socket 30 | # KukaVarProxy actively listens on TCP port 7000 31 | def __init__(self, TCP_IP): 32 | try: 33 | client.connect((TCP_IP, 7000)) 34 | except: 35 | self.error_list(1) 36 | 37 | # Sending messages on the KukaVarProxy message format: 38 | # Msg ID in HEX 2 bytes 39 | # Msg length in HEX 2 bytes 40 | # Read (0) or write (1) 1 byte 41 | # Variable name length in HEX 2 bytes 42 | # Variable name in ASCII # bytes 43 | # Variable value length in HEX 2 bytes 44 | # Variable value in ASCII # bytes 45 | def send (self, var, val, msgID): 46 | try: 47 | msg = bytearray() 48 | temp = bytearray() 49 | if val != "": 50 | val = str(val) 51 | msg.append((len(val) & 0xff00) >> 8) 52 | msg.append((len(val) & 0x00ff)) 53 | msg.extend(map(ord, val)) 54 | temp.append(bool(val)) 55 | temp.append(((len(var)) & 0xff00) >> 8) 56 | temp.append((len(var)) & 0x00ff) 57 | temp.extend(map(ord, var)) 58 | msg = temp + msg 59 | del temp[:] 60 | temp.append((msgID & 0xff00) >> 8) 61 | temp.append(msgID & 0x00ff) 62 | temp.append((len(msg) & 0xff00) >> 8) 63 | temp.append((len(msg) & 0x00ff)) 64 | msg = temp + msg 65 | except : 66 | self.error_list(2) 67 | try: 68 | client.send(msg) 69 | return client.recv(1024) 70 | except : 71 | self.error_list(1) 72 | 73 | # Get variables from KukaVarProxy response format 74 | def __get_var(self, msg): 75 | try: 76 | lsb = int( msg[5]) 77 | msb = int( msg[6]) 78 | lenValue = (lsb <<8 | msb) 79 | return str(msg [7: 7+lenValue],'utf-8') 80 | except: 81 | self.error_list(2) 82 | 83 | # Read variables from KukaVarProxy 84 | def read (self, var, msgID=0): 85 | try: 86 | return self.__get_var(self.send(var,"",msgID)) 87 | except : 88 | self.error_list(2) 89 | 90 | # Write variables to KukaVarProxy 91 | def write (self, var, val, msgID=0): 92 | try: 93 | if val != (""): return self.__get_var(self.send(var,val,msgID)) 94 | else: raise self.error_list(3) 95 | except : 96 | self.error_list(2) 97 | 98 | # Close socket 99 | def disconnect (self): 100 | client.close() 101 | 102 | # In case of error 103 | def error_list (self, ID): 104 | if ID == 1: 105 | print ("Network Error (tcp_error)") 106 | print ("Check your KRC's IP address on the network, and make sure kukaproxyvar is running.") 107 | self.disconnect() 108 | raise SystemExit 109 | elif ID == 2: 110 | print ("Python Error.") 111 | print ("Check the code and uncomment the lines related to your python version.") 112 | self.disconnect() 113 | raise SystemExit 114 | elif ID == 3: 115 | print ("Error in write() statement.") 116 | print ("Variable value is not defined.") 117 | 118 | # Plot figure 119 | def plot_fig(xmin, xmax, ymin, ymax): 120 | plt.axis([xmin, xmax, ymin, ymax]) 121 | plt.title('Current motor temperature of KUKA KR 16-2, Axis 1-6') 122 | plt.grid(True) 123 | plt.xlabel('time [s*10]') 124 | plt.ylabel('Motor temperature [' + u'\u2103' + ']') 125 | plt.ion() 126 | 127 | # Construct a colormap 128 | cmap = clr.LinearSegmentedColormap.from_list('cmap for Dennis Hein', [(0, '#ff0000'), (70/100., '#ffff00'), (100/100., '#00ff00')], N=64) 129 | X = [[.0, .0], [1.0, 1.0]] 130 | plt.imshow(X, interpolation='bicubic', cmap = cmap, extent=(xmin, xmax, ymin, ymax), alpha = 0.3) 131 | 132 | def plot_values(): 133 | plt.plot(plotted_values_A1, 'b', label='Axis 1') 134 | plt.plot(plotted_values_A2, 'r', label='Axis 2') 135 | plt.plot(plotted_values_A3, 'g', label='Axis 3') 136 | plt.plot(plotted_values_A4, 'c', label='Axis 4') 137 | plt.plot(plotted_values_A5, 'm', label='Axis 5') 138 | plt.plot(plotted_values_A6, 'y', label='Axis 6') 139 | 140 | if __name__ == "__main__": 141 | # Initialize OPC-UA Client connection 142 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 143 | 144 | # Setup robot object 145 | robot = KUKA('192.168.250.16') 146 | 147 | # Setup server 148 | server = Server() 149 | server.set_endpoint("opc.tcp://192.168.250.200:50895") 150 | 151 | # Setup namespace 152 | uri = "http://examples.freeopcua.github.io" 153 | idx = server.register_namespace(uri) 154 | 155 | # Get objects node 156 | objects = server.get_objects_node() 157 | 158 | # Populating address space 159 | myObject = objects.add_object(idx, "KUKA_KR16_2") 160 | 161 | # Adding desired variables 162 | A1 = myObject.add_variable(idx, "A1", 6.7) 163 | A2 = myObject.add_variable(idx, "A2", 6.7) 164 | A3 = myObject.add_variable(idx, "A3", 6.7) 165 | A4 = myObject.add_variable(idx, "A4", 6.7) 166 | A5 = myObject.add_variable(idx, "A5", 6.7) 167 | A6 = myObject.add_variable(idx, "A6", 6.7) 168 | 169 | A1.set_writable() 170 | A2.set_writable() 171 | A3.set_writable() 172 | A4.set_writable() 173 | A5.set_writable() 174 | A6.set_writable() 175 | 176 | # Starting OPC-UA Server 177 | server.start() 178 | 179 | # Start plot 180 | xmin, xmax, ymin, ymax = 0, 200, 15, 100 181 | plot_fig(xmin, xmax, ymin, ymax) 182 | 183 | count = 0 184 | 185 | plotted_values_A1 = [] 186 | plotted_values_A2 = [] 187 | plotted_values_A3 = [] 188 | plotted_values_A4 = [] 189 | plotted_values_A5 = [] 190 | plotted_values_A6 = [] 191 | 192 | plot_values() 193 | plt.legend() 194 | 195 | try: 196 | count = 0 197 | offset = 273.15 # Kelvin to celcius 198 | while True: 199 | time.sleep(0.1) 200 | 201 | output = robot.read("$AXIS_ACT") 202 | output = output.replace(",", "") 203 | output_elements = output.split(" ") 204 | 205 | A1.set_value(output_elements[2]) 206 | A2.set_value(output_elements[4]) 207 | A3.set_value(output_elements[6]) 208 | A4.set_value(output_elements[8]) 209 | A5.set_value(output_elements[10]) 210 | A6.set_value(output_elements[12]) 211 | 212 | plotted_values_A1.append(float(robot.read("$MOT_TEMP [1]")) - offset) 213 | plotted_values_A2.append(float(robot.read("$MOT_TEMP [2]")) - offset) 214 | plotted_values_A3.append(float(robot.read("$MOT_TEMP [3]")) - offset) 215 | plotted_values_A4.append(float(robot.read("$MOT_TEMP [4]")) - offset) 216 | plotted_values_A5.append(float(robot.read("$MOT_TEMP [5]")) - offset) 217 | plotted_values_A6.append(float(robot.read("$MOT_TEMP [6]")) - offset) 218 | 219 | plot_values() 220 | 221 | plt.pause(0.00001) 222 | count+=1 223 | 224 | # Resizing plot 225 | if(count+20 > xmax): 226 | xmin+=100 227 | xmax+=100 228 | plt.axis([xmin, xmax, ymin, ymax]) 229 | plt.clf() 230 | plot_fig(xmin, xmax, ymin, ymax) 231 | plot_values() 232 | plt.legend() 233 | 234 | finally: 235 | #close connection, remove subcsriptions, etc 236 | server.stop() -------------------------------------------------------------------------------- /opcua-server/opcua-server-torque-to-file.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Source code for an OPC UA server able to extract axis variables 3 | from a KUKA KR C4 robot controller and send them to an 4 | OPC UA client. The server also extracts information about the 5 | current torque on each of the motors controlling the different 6 | KUKA robot axis and writes the data to a .csv file called 7 | "KUKA_KR16_2_motorTorque.csv". 8 | 9 | Based on work by: 10 | - Massimiliano Fago (https://sourceforge.net/projects/openshowvar) 11 | - Mechatronics Lab at AAlesund University College 12 | (https://github.com/aauc-mechlab/JOpenShowVar) 13 | - Ahmad Saeed (https://github.com/akselov/kukavarproxy-msg-format) 14 | - Olivier Roulet-Dubonnet (https://github.com/FreeOpcUa) 15 | 16 | Author: Aksel Oevern 17 | NTNU 2018 18 | ''' 19 | 20 | import sys 21 | import socket 22 | sys.path.insert(0, "..") 23 | import time 24 | from opcua import ua, Server 25 | 26 | class KUKA(object): 27 | # Open socket 28 | # KukaVarProxy actively listens on TCP port 7000 29 | def __init__(self, TCP_IP): 30 | try: 31 | client.connect((TCP_IP, 7000)) 32 | except: 33 | self.error_list(1) 34 | 35 | # Sending messages on the KukaVarProxy message format: 36 | # Msg ID in HEX 2 bytes 37 | # Msg length in HEX 2 bytes 38 | # Read (0) or write (1) 1 byte 39 | # Variable name length in HEX 2 bytes 40 | # Variable name in ASCII # bytes 41 | # Variable value length in HEX 2 bytes 42 | # Variable value in ASCII # bytes 43 | def send (self, var, val, msgID): 44 | try: 45 | msg = bytearray() 46 | temp = bytearray() 47 | if val != "": 48 | val = str(val) 49 | msg.append((len(val) & 0xff00) >> 8) 50 | msg.append((len(val) & 0x00ff)) 51 | msg.extend(map(ord, val)) 52 | temp.append(bool(val)) 53 | temp.append(((len(var)) & 0xff00) >> 8) 54 | temp.append((len(var)) & 0x00ff) 55 | temp.extend(map(ord, var)) 56 | msg = temp + msg 57 | del temp[:] 58 | temp.append((msgID & 0xff00) >> 8) 59 | temp.append(msgID & 0x00ff) 60 | temp.append((len(msg) & 0xff00) >> 8) 61 | temp.append((len(msg) & 0x00ff)) 62 | msg = temp + msg 63 | except : 64 | self.error_list(2) 65 | try: 66 | client.send(msg) 67 | return client.recv(1024) 68 | except : 69 | self.error_list(1) 70 | 71 | # Get variables from KukaVarProxy response format 72 | def __get_var(self, msg): 73 | try: 74 | lsb = int( msg[5]) 75 | msb = int( msg[6]) 76 | lenValue = (lsb <<8 | msb) 77 | return str(msg [7: 7+lenValue],'utf-8') 78 | except: 79 | self.error_list(2) 80 | 81 | # Read variables from KukaVarProxy 82 | def read (self, var, msgID=0): 83 | try: 84 | return self.__get_var(self.send(var,"",msgID)) 85 | except : 86 | self.error_list(2) 87 | 88 | # Write variables to KukaVarProxy 89 | def write (self, var, val, msgID=0): 90 | try: 91 | if val != (""): return self.__get_var(self.send(var,val,msgID)) 92 | else: raise self.error_list(3) 93 | except : 94 | self.error_list(2) 95 | 96 | # Close socket 97 | def disconnect (self): 98 | client.close() 99 | 100 | # In case of error 101 | def error_list (self, ID): 102 | if ID == 1: 103 | print ("Network Error (tcp_error)") 104 | print ("Check your KRC's IP address on the network, and make sure kukaproxyvar is running.") 105 | self.disconnect() 106 | raise SystemExit 107 | elif ID == 2: 108 | print ("Python Error.") 109 | print ("Check the code and uncomment the lines related to your python version.") 110 | self.disconnect() 111 | raise SystemExit 112 | elif ID == 3: 113 | print ("Error in write() statement.") 114 | print ("Variable value is not defined.") 115 | 116 | if __name__ == "__main__": 117 | # Initialize OPC-UA Client connection 118 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 119 | 120 | # Setup robot object 121 | robot = KUKA('192.168.250.16') 122 | 123 | # Setup server 124 | server = Server() 125 | server.set_endpoint("opc.tcp://192.168.250.200:50895") 126 | 127 | # Setup namespace 128 | uri = "http://examples.freeopcua.github.io" 129 | idx = server.register_namespace(uri) 130 | 131 | # Get objects node 132 | objects = server.get_objects_node() 133 | 134 | # Populating address space 135 | myObject = objects.add_object(idx, "KUKA_KR16_2") 136 | 137 | # Adding desired variables 138 | A1 = myObject.add_variable(idx, "A1", 6.7) 139 | A2 = myObject.add_variable(idx, "A2", 6.7) 140 | A3 = myObject.add_variable(idx, "A3", 6.7) 141 | A4 = myObject.add_variable(idx, "A4", 6.7) 142 | A5 = myObject.add_variable(idx, "A5", 6.7) 143 | A6 = myObject.add_variable(idx, "A6", 6.7) 144 | 145 | A1.set_writable() 146 | A2.set_writable() 147 | A3.set_writable() 148 | A4.set_writable() 149 | A5.set_writable() 150 | A6.set_writable() 151 | 152 | # Starting OPC-UA Server 153 | server.start() 154 | 155 | # Values to be written 156 | values_A1 = [] 157 | values_A2 = [] 158 | values_A3 = [] 159 | values_A4 = [] 160 | values_A5 = [] 161 | values_A6 = [] 162 | 163 | try: 164 | # Timer for monitoring interval 165 | count = 0 166 | timer = 100 167 | while(count < timer): 168 | time.sleep(0.1) 169 | count+=1 170 | 171 | output = robot.read("$AXIS_ACT") 172 | output = output.replace(",", "") 173 | output_elements = output.split(" ") 174 | 175 | A1.set_value(output_elements[2]) 176 | A2.set_value(output_elements[4]) 177 | A3.set_value(output_elements[6]) 178 | A4.set_value(output_elements[8]) 179 | A5.set_value(output_elements[10]) 180 | A6.set_value(output_elements[12]) 181 | 182 | values_A1.append(float(robot.read("$TORQUE_AXIS_ACT [1]"))) 183 | values_A2.append(float(robot.read("$TORQUE_AXIS_ACT [2]"))) 184 | values_A3.append(float(robot.read("$TORQUE_AXIS_ACT [3]"))) 185 | values_A4.append(float(robot.read("$TORQUE_AXIS_ACT [4]"))) 186 | values_A5.append(float(robot.read("$TORQUE_AXIS_ACT [5]"))) 187 | values_A6.append(float(robot.read("$TORQUE_AXIS_ACT [6]"))) 188 | 189 | f = open('KUKA_KR16_2_motorTorque.csv', 'w') 190 | 191 | for i in range(0, len(values_A1)): 192 | f.write(str(values_A1[i]) + ",") 193 | f.write(str(values_A2[i]) + ",") 194 | f.write(str(values_A3[i]) + ",") 195 | f.write(str(values_A4[i]) + ",") 196 | f.write(str(values_A5[i]) + ",") 197 | f.write(str(values_A6[i]) + "\n") 198 | 199 | f.close() 200 | 201 | finally: 202 | # Close OPC UA client connection, remove subcsriptions, etc 203 | server.stop() -------------------------------------------------------------------------------- /opcua-server/opcua-server-torque.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Source code for an OPC UA server able to extract axis variables 3 | from a KUKA KR C4 robot controller and send them to an 4 | OPC UA client. The server also extracts information about the 5 | current torque on each of the motors controlling the different 6 | KUKA robot axis and does a real-time plot of all the values. 7 | 8 | Based on work by: 9 | - Massimiliano Fago (https://sourceforge.net/projects/openshowvar) 10 | - Mechatronics Lab at AAlesund University College 11 | (https://github.com/aauc-mechlab/JOpenShowVar) 12 | - Ahmad Saeed (https://github.com/akselov/kukavarproxy-msg-format) 13 | - Olivier Roulet-Dubonnet (https://github.com/FreeOpcUa) 14 | 15 | Author: Aksel Oevern 16 | NTNU 2018 17 | ''' 18 | 19 | import sys 20 | import socket 21 | sys.path.insert(0, "..") 22 | import time 23 | import numpy as np 24 | import matplotlib.pyplot as plt 25 | from opcua import ua, Server 26 | 27 | class KUKA(object): 28 | # Open socket 29 | # KukaVarProxy actively listens on TCP port 7000 30 | def __init__(self, TCP_IP): 31 | try: 32 | client.connect((TCP_IP, 7000)) 33 | except: 34 | self.error_list(1) 35 | 36 | # Sending messages on the KukaVarProxy message format: 37 | # Msg ID in HEX 2 bytes 38 | # Msg length in HEX 2 bytes 39 | # Read (0) or write (1) 1 byte 40 | # Variable name length in HEX 2 bytes 41 | # Variable name in ASCII # bytes 42 | # Variable value length in HEX 2 bytes 43 | # Variable value in ASCII # bytes 44 | def send (self, var, val, msgID): 45 | try: 46 | msg = bytearray() 47 | temp = bytearray() 48 | if val != "": 49 | val = str(val) 50 | msg.append((len(val) & 0xff00) >> 8) 51 | msg.append((len(val) & 0x00ff)) 52 | msg.extend(map(ord, val)) 53 | temp.append(bool(val)) 54 | temp.append(((len(var)) & 0xff00) >> 8) 55 | temp.append((len(var)) & 0x00ff) 56 | temp.extend(map(ord, var)) 57 | msg = temp + msg 58 | del temp[:] 59 | temp.append((msgID & 0xff00) >> 8) 60 | temp.append(msgID & 0x00ff) 61 | temp.append((len(msg) & 0xff00) >> 8) 62 | temp.append((len(msg) & 0x00ff)) 63 | msg = temp + msg 64 | except : 65 | self.error_list(2) 66 | try: 67 | client.send(msg) 68 | return client.recv(1024) 69 | except : 70 | self.error_list(1) 71 | 72 | # Get variables from KukaVarProxy response format 73 | def __get_var(self, msg): 74 | try: 75 | lsb = int( msg[5]) 76 | msb = int( msg[6]) 77 | lenValue = (lsb <<8 | msb) 78 | return str(msg [7: 7+lenValue],'utf-8') 79 | except: 80 | self.error_list(2) 81 | 82 | # Read variables from KukaVarProxy 83 | def read (self, var, msgID=0): 84 | try: 85 | return self.__get_var(self.send(var,"",msgID)) 86 | except : 87 | self.error_list(2) 88 | 89 | # Write variables to KukaVarProxy 90 | def write (self, var, val, msgID=0): 91 | try: 92 | if val != (""): return self.__get_var(self.send(var,val,msgID)) 93 | else: raise self.error_list(3) 94 | except : 95 | self.error_list(2) 96 | 97 | # Close socket 98 | def disconnect (self): 99 | client.close() 100 | 101 | # In case of error 102 | def error_list (self, ID): 103 | if ID == 1: 104 | print ("Network Error (tcp_error)") 105 | print ("Check your KRC's IP address on the network, and make sure kukaproxyvar is running.") 106 | self.disconnect() 107 | raise SystemExit 108 | elif ID == 2: 109 | print ("Python Error.") 110 | print ("Check the code and uncomment the lines related to your python version.") 111 | self.disconnect() 112 | raise SystemExit 113 | elif ID == 3: 114 | print ("Error in write() statement.") 115 | print ("Variable value is not defined.") 116 | 117 | if __name__ == "__main__": 118 | # Initialize OPC-UA Client connection 119 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 120 | 121 | # Setup robot object 122 | robot = KUKA('192.168.250.16') 123 | 124 | # Setup server 125 | server = Server() 126 | server.set_endpoint("opc.tcp://192.168.250.200:50895") 127 | 128 | # Setup namespace 129 | uri = "http://examples.freeopcua.github.io" 130 | idx = server.register_namespace(uri) 131 | 132 | # Get objects node 133 | objects = server.get_objects_node() 134 | 135 | # Populating address space 136 | myObject = objects.add_object(idx, "KUKA_KR16_2") 137 | 138 | # Adding desired variables 139 | A1 = myObject.add_variable(idx, "A1", 6.7) 140 | A2 = myObject.add_variable(idx, "A2", 6.7) 141 | A3 = myObject.add_variable(idx, "A3", 6.7) 142 | A4 = myObject.add_variable(idx, "A4", 6.7) 143 | A5 = myObject.add_variable(idx, "A5", 6.7) 144 | A6 = myObject.add_variable(idx, "A6", 6.7) 145 | 146 | A1.set_writable() 147 | A2.set_writable() 148 | A3.set_writable() 149 | A4.set_writable() 150 | A5.set_writable() 151 | A6.set_writable() 152 | 153 | # Starting OPC-UA Server 154 | server.start() 155 | 156 | # Start plot 157 | xaxis_t0 = 100 158 | plt.axis([0, xaxis_t0, -1000, 1000]) 159 | plt.title('Current motor torque of KUKA KR 16-2, Axis 1-6') 160 | plt.grid(True) 161 | plt.xlabel('time [s*10]') 162 | plt.ylabel('Current motor torque [Nm]') 163 | plt.ion() 164 | count = 0 165 | 166 | plotted_values_A1 = [] 167 | plotted_values_A2 = [] 168 | plotted_values_A3 = [] 169 | plotted_values_A4 = [] 170 | plotted_values_A5 = [] 171 | plotted_values_A6 = [] 172 | 173 | plt.plot(plotted_values_A1, 'b', label='Axis 1') 174 | plt.plot(plotted_values_A2, 'r', label='Axis 2') 175 | plt.plot(plotted_values_A3, 'g', label='Axis 3') 176 | plt.plot(plotted_values_A4, 'c', label='Axis 4') 177 | plt.plot(plotted_values_A5, 'm', label='Axis 5') 178 | plt.plot(plotted_values_A6, 'y', label='Axis 6') 179 | 180 | plt.legend() 181 | 182 | try: 183 | count = 0 184 | while True: 185 | time.sleep(0.1) 186 | 187 | output = robot.read("$AXIS_ACT") 188 | output = output.replace(",", "") 189 | output_elements = output.split(" ") 190 | 191 | A1.set_value(output_elements[2]) 192 | A2.set_value(output_elements[4]) 193 | A3.set_value(output_elements[6]) 194 | A4.set_value(output_elements[8]) 195 | A5.set_value(output_elements[10]) 196 | A6.set_value(output_elements[12]) 197 | 198 | plotted_values_A1.append(float(robot.read("$TORQUE_AXIS_ACT [1]"))) 199 | plotted_values_A2.append(float(robot.read("$TORQUE_AXIS_ACT [2]"))) 200 | plotted_values_A3.append(float(robot.read("$TORQUE_AXIS_ACT [3]"))) 201 | plotted_values_A4.append(float(robot.read("$TORQUE_AXIS_ACT [4]"))) 202 | plotted_values_A5.append(float(robot.read("$TORQUE_AXIS_ACT [5]"))) 203 | plotted_values_A6.append(float(robot.read("$TORQUE_AXIS_ACT [6]"))) 204 | 205 | plt.plot(plotted_values_A1, 'b', label='Axis 1') 206 | plt.plot(plotted_values_A2, 'r', label='Axis 2') 207 | plt.plot(plotted_values_A3, 'g', label='Axis 3') 208 | plt.plot(plotted_values_A4, 'c', label='Axis 4') 209 | plt.plot(plotted_values_A5, 'm', label='Axis 5') 210 | plt.plot(plotted_values_A6, 'y', label='Axis 6') 211 | 212 | plt.pause(0.00001) 213 | count+=1 214 | 215 | # Resizing plot 216 | if(count+20 > xaxis_t0): 217 | xaxis_t0+=50 218 | plt.axis([0, xaxis_t0, -1000, 1000]) 219 | 220 | finally: 221 | # Close OPC UA client connection, remove subcsriptions, etc 222 | server.stop() -------------------------------------------------------------------------------- /opcua-server/opcua-server-velocity-to-file.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Source code for an OPC UA server able to extract axis variables 3 | from a KUKA KR C4 robot controller and send them to an 4 | OPC UA client. The server also extracts information about the 5 | current velocity of each of the motors controlling the different 6 | KUKA robot axis and writes the data to a .csv file called 7 | "KUKA_KR16_2_motorSpeed.csv". 8 | 9 | Based on work by: 10 | - Massimiliano Fago (https://sourceforge.net/projects/openshowvar) 11 | - Mechatronics Lab at AAlesund University College 12 | (https://github.com/aauc-mechlab/JOpenShowVar) 13 | - Ahmad Saeed (https://github.com/akselov/kukavarproxy-msg-format) 14 | - Olivier Roulet-Dubonnet (https://github.com/FreeOpcUa) 15 | 16 | Author: Aksel Oevern 17 | NTNU 2018 18 | ''' 19 | 20 | import sys 21 | import socket 22 | sys.path.insert(0, "..") 23 | import time 24 | from opcua import ua, Server 25 | 26 | class KUKA(object): 27 | # Open socket 28 | # KukaVarProxy actively listens on TCP port 7000 29 | def __init__(self, TCP_IP): 30 | try: 31 | client.connect((TCP_IP, 7000)) 32 | except: 33 | self.error_list(1) 34 | 35 | # Sending messages on the KukaVarProxy message format: 36 | # Msg ID in HEX 2 bytes 37 | # Msg length in HEX 2 bytes 38 | # Read (0) or write (1) 1 byte 39 | # Variable name length in HEX 2 bytes 40 | # Variable name in ASCII # bytes 41 | # Variable value length in HEX 2 bytes 42 | # Variable value in ASCII # bytes 43 | def send (self, var, val, msgID): 44 | try: 45 | msg = bytearray() 46 | temp = bytearray() 47 | if val != "": 48 | val = str(val) 49 | msg.append((len(val) & 0xff00) >> 8) 50 | msg.append((len(val) & 0x00ff)) 51 | msg.extend(map(ord, val)) 52 | temp.append(bool(val)) 53 | temp.append(((len(var)) & 0xff00) >> 8) 54 | temp.append((len(var)) & 0x00ff) 55 | temp.extend(map(ord, var)) 56 | msg = temp + msg 57 | del temp[:] 58 | temp.append((msgID & 0xff00) >> 8) 59 | temp.append(msgID & 0x00ff) 60 | temp.append((len(msg) & 0xff00) >> 8) 61 | temp.append((len(msg) & 0x00ff)) 62 | msg = temp + msg 63 | except : 64 | self.error_list(2) 65 | try: 66 | client.send(msg) 67 | return client.recv(1024) 68 | except : 69 | self.error_list(1) 70 | 71 | # Get variables from KukaVarProxy response format 72 | def __get_var(self, msg): 73 | try: 74 | lsb = int( msg[5]) 75 | msb = int( msg[6]) 76 | lenValue = (lsb <<8 | msb) 77 | return str(msg [7: 7+lenValue],'utf-8') 78 | except: 79 | self.error_list(2) 80 | 81 | # Read variables from KukaVarProxy 82 | def read (self, var, msgID=0): 83 | try: 84 | return self.__get_var(self.send(var,"",msgID)) 85 | except : 86 | self.error_list(2) 87 | 88 | # Write variables to KukaVarProxy 89 | def write (self, var, val, msgID=0): 90 | try: 91 | if val != (""): return self.__get_var(self.send(var,val,msgID)) 92 | else: raise self.error_list(3) 93 | except : 94 | self.error_list(2) 95 | 96 | # Close socket 97 | def disconnect (self): 98 | client.close() 99 | 100 | # In case of error 101 | def error_list (self, ID): 102 | if ID == 1: 103 | print ("Network Error (tcp_error)") 104 | print ("Check your KRC's IP address on the network, and make sure kukaproxyvar is running.") 105 | self.disconnect() 106 | raise SystemExit 107 | elif ID == 2: 108 | print ("Python Error.") 109 | print ("Check the code and uncomment the lines related to your python version.") 110 | self.disconnect() 111 | raise SystemExit 112 | elif ID == 3: 113 | print ("Error in write() statement.") 114 | print ("Variable value is not defined.") 115 | 116 | if __name__ == "__main__": 117 | # Initialize OPC-UA Client connection 118 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 119 | 120 | # Setup robot object 121 | robot = KUKA('192.168.250.16') 122 | 123 | # Setup server 124 | server = Server() 125 | server.set_endpoint("opc.tcp://192.168.250.200:50895") 126 | 127 | # Setup namespace 128 | uri = "http://examples.freeopcua.github.io" 129 | idx = server.register_namespace(uri) 130 | 131 | # Get objects node 132 | objects = server.get_objects_node() 133 | 134 | # Populating address space 135 | myObject = objects.add_object(idx, "KUKA_KR16_2") 136 | 137 | # Adding desired variables 138 | A1 = myObject.add_variable(idx, "A1", 6.7) 139 | A2 = myObject.add_variable(idx, "A2", 6.7) 140 | A3 = myObject.add_variable(idx, "A3", 6.7) 141 | A4 = myObject.add_variable(idx, "A4", 6.7) 142 | A5 = myObject.add_variable(idx, "A5", 6.7) 143 | A6 = myObject.add_variable(idx, "A6", 6.7) 144 | 145 | A1.set_writable() 146 | A2.set_writable() 147 | A3.set_writable() 148 | A4.set_writable() 149 | A5.set_writable() 150 | A6.set_writable() 151 | 152 | # Starting OPC-UA Server 153 | server.start() 154 | 155 | # Values to be written 156 | values_A1 = [] 157 | values_A2 = [] 158 | values_A3 = [] 159 | values_A4 = [] 160 | values_A5 = [] 161 | values_A6 = [] 162 | 163 | try: 164 | # Timer for monitoring interval 165 | count = 0 166 | timer = 100 167 | while(count < timer): 168 | time.sleep(0.1) 169 | count+=1 170 | 171 | output = robot.read("$AXIS_ACT") 172 | output = output.replace(",", "") 173 | output_elements = output.split(" ") 174 | 175 | A1.set_value(output_elements[2]) 176 | A2.set_value(output_elements[4]) 177 | A3.set_value(output_elements[6]) 178 | A4.set_value(output_elements[8]) 179 | A5.set_value(output_elements[10]) 180 | A6.set_value(output_elements[12]) 181 | 182 | values_A1.append(float(robot.read("$VEL_AXIS_ACT [1]"))*10) 183 | values_A2.append(float(robot.read("$VEL_AXIS_ACT [2]"))*10) 184 | values_A3.append(float(robot.read("$VEL_AXIS_ACT [3]"))*10) 185 | values_A4.append(float(robot.read("$VEL_AXIS_ACT [4]"))*10) 186 | values_A5.append(float(robot.read("$VEL_AXIS_ACT [5]"))*10) 187 | values_A6.append(float(robot.read("$VEL_AXIS_ACT [6]"))*10) 188 | 189 | f = open('KUKA_KR16_2_motorSpeed.csv', 'w') 190 | 191 | for i in range(0, len(values_A1)): 192 | f.write(str(values_A1[i]) + ",") 193 | f.write(str(values_A2[i]) + ",") 194 | f.write(str(values_A3[i]) + ",") 195 | f.write(str(values_A4[i]) + ",") 196 | f.write(str(values_A5[i]) + ",") 197 | f.write(str(values_A6[i]) + "\n") 198 | 199 | f.close() 200 | 201 | finally: 202 | # Close OPC UA client connection, remove subcsriptions, etc 203 | server.stop() -------------------------------------------------------------------------------- /opcua-server/opcua-server-velocity.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Source code for an OPC UA server able to extract axis variables 3 | from a KUKA KR C4 robot controller and send them to an 4 | OPC UA client. The server also extracts information about the 5 | current velocity of each of the motors controlling the different 6 | KUKA robot axis and does a real-time plot of all the values. 7 | 8 | Based on work by: 9 | - Massimiliano Fago (https://sourceforge.net/projects/openshowvar) 10 | - Mechatronics Lab at AAlesund University College 11 | (https://github.com/aauc-mechlab/JOpenShowVar) 12 | - Ahmad Saeed (https://github.com/akselov/kukavarproxy-msg-format) 13 | - Olivier Roulet-Dubonnet (https://github.com/FreeOpcUa) 14 | 15 | Author: Aksel Oevern 16 | NTNU 2018 17 | ''' 18 | 19 | import sys 20 | import socket 21 | sys.path.insert(0, "..") 22 | import time 23 | import numpy as np 24 | import matplotlib.pyplot as plt 25 | from opcua import ua, Server 26 | 27 | class KUKA(object): 28 | # Open socket 29 | # KukaVarProxy actively listens on TCP port 7000 30 | def __init__(self, TCP_IP): 31 | try: 32 | client.connect((TCP_IP, 7000)) 33 | except: 34 | self.error_list(1) 35 | 36 | # Sending messages on the KukaVarProxy message format: 37 | # Msg ID in HEX 2 bytes 38 | # Msg length in HEX 2 bytes 39 | # Read (0) or write (1) 1 byte 40 | # Variable name length in HEX 2 bytes 41 | # Variable name in ASCII # bytes 42 | # Variable value length in HEX 2 bytes 43 | # Variable value in ASCII # bytes 44 | def send (self, var, val, msgID): 45 | try: 46 | msg = bytearray() 47 | temp = bytearray() 48 | if val != "": 49 | val = str(val) 50 | msg.append((len(val) & 0xff00) >> 8) 51 | msg.append((len(val) & 0x00ff)) 52 | msg.extend(map(ord, val)) 53 | temp.append(bool(val)) 54 | temp.append(((len(var)) & 0xff00) >> 8) 55 | temp.append((len(var)) & 0x00ff) 56 | temp.extend(map(ord, var)) 57 | msg = temp + msg 58 | del temp[:] 59 | temp.append((msgID & 0xff00) >> 8) 60 | temp.append(msgID & 0x00ff) 61 | temp.append((len(msg) & 0xff00) >> 8) 62 | temp.append((len(msg) & 0x00ff)) 63 | msg = temp + msg 64 | except : 65 | self.error_list(2) 66 | try: 67 | client.send(msg) 68 | return client.recv(1024) 69 | except : 70 | self.error_list(1) 71 | 72 | # Get variables from KukaVarProxy response format 73 | def __get_var(self, msg): 74 | try: 75 | lsb = int( msg[5]) 76 | msb = int( msg[6]) 77 | lenValue = (lsb <<8 | msb) 78 | return str(msg [7: 7+lenValue],'utf-8') 79 | except: 80 | self.error_list(2) 81 | 82 | # Read variables from KukaVarProxy 83 | def read (self, var, msgID=0): 84 | try: 85 | return self.__get_var(self.send(var,"",msgID)) 86 | except : 87 | self.error_list(2) 88 | 89 | # Write variables to KukaVarProxy 90 | def write (self, var, val, msgID=0): 91 | try: 92 | if val != (""): return self.__get_var(self.send(var,val,msgID)) 93 | else: raise self.error_list(3) 94 | except : 95 | self.error_list(2) 96 | 97 | # Close socket 98 | def disconnect (self): 99 | client.close() 100 | 101 | # In case of error 102 | def error_list (self, ID): 103 | if ID == 1: 104 | print ("Network Error (tcp_error)") 105 | print ("Check your KRC's IP address on the network, and make sure kukaproxyvar is running.") 106 | self.disconnect() 107 | raise SystemExit 108 | elif ID == 2: 109 | print ("Python Error.") 110 | print ("Check the code and uncomment the lines related to your python version.") 111 | self.disconnect() 112 | raise SystemExit 113 | elif ID == 3: 114 | print ("Error in write() statement.") 115 | print ("Variable value is not defined.") 116 | 117 | if __name__ == "__main__": 118 | # Initialize OPC-UA Client connection 119 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 120 | 121 | # Setup robot object 122 | robot = KUKA('192.168.250.16') 123 | 124 | # Setup server 125 | server = Server() 126 | server.set_endpoint("opc.tcp://192.168.250.200:50895") 127 | 128 | # Setup namespace 129 | uri = "http://examples.freeopcua.github.io" 130 | idx = server.register_namespace(uri) 131 | 132 | # Get objects node 133 | objects = server.get_objects_node() 134 | 135 | # Populating address space 136 | myObject = objects.add_object(idx, "KUKA_KR16_2") 137 | 138 | # Adding desired variables 139 | A1 = myObject.add_variable(idx, "A1", 6.7) 140 | A2 = myObject.add_variable(idx, "A2", 6.7) 141 | A3 = myObject.add_variable(idx, "A3", 6.7) 142 | A4 = myObject.add_variable(idx, "A4", 6.7) 143 | A5 = myObject.add_variable(idx, "A5", 6.7) 144 | A6 = myObject.add_variable(idx, "A6", 6.7) 145 | 146 | A1.set_writable() 147 | A2.set_writable() 148 | A3.set_writable() 149 | A4.set_writable() 150 | A5.set_writable() 151 | A6.set_writable() 152 | 153 | # Starting OPC-UA Server 154 | server.start() 155 | 156 | # Start plot 157 | xaxis_t0 = 100 158 | plt.axis([0, xaxis_t0, -100, 100]) 159 | plt.title('Current motor speed of KUKA KR 16-2, Axis 1-6') 160 | plt.grid(True) 161 | plt.xlabel('time [s*10]') 162 | plt.ylabel('Current motor speed [%]') 163 | plt.ion() 164 | count = 0 165 | 166 | plotted_values_A1 = [] 167 | plotted_values_A2 = [] 168 | plotted_values_A3 = [] 169 | plotted_values_A4 = [] 170 | plotted_values_A5 = [] 171 | plotted_values_A6 = [] 172 | 173 | plt.plot(plotted_values_A1, 'b', label='Axis 1') 174 | plt.plot(plotted_values_A2, 'r', label='Axis 2') 175 | plt.plot(plotted_values_A3, 'g', label='Axis 3') 176 | plt.plot(plotted_values_A4, 'c', label='Axis 4') 177 | plt.plot(plotted_values_A5, 'm', label='Axis 5') 178 | plt.plot(plotted_values_A6, 'y', label='Axis 6') 179 | 180 | plt.legend() 181 | 182 | try: 183 | count = 0 184 | while True: 185 | time.sleep(0.1) 186 | 187 | output = robot.read("$AXIS_ACT") 188 | output = output.replace(",", "") 189 | output_elements = output.split(" ") 190 | 191 | A1.set_value(output_elements[2]) 192 | A2.set_value(output_elements[4]) 193 | A3.set_value(output_elements[6]) 194 | A4.set_value(output_elements[8]) 195 | A5.set_value(output_elements[10]) 196 | A6.set_value(output_elements[12]) 197 | 198 | plotted_values_A1.append(float(robot.read("$VEL_AXIS_ACT [1]"))) 199 | plotted_values_A2.append(float(robot.read("$VEL_AXIS_ACT [2]"))) 200 | plotted_values_A3.append(float(robot.read("$VEL_AXIS_ACT [3]"))) 201 | plotted_values_A4.append(float(robot.read("$VEL_AXIS_ACT [4]"))) 202 | plotted_values_A5.append(float(robot.read("$VEL_AXIS_ACT [5]"))) 203 | plotted_values_A6.append(float(robot.read("$VEL_AXIS_ACT [6]"))) 204 | 205 | plt.plot(plotted_values_A1, 'b', label='Axis 1') 206 | plt.plot(plotted_values_A2, 'r', label='Axis 2') 207 | plt.plot(plotted_values_A3, 'g', label='Axis 3') 208 | plt.plot(plotted_values_A4, 'c', label='Axis 4') 209 | plt.plot(plotted_values_A5, 'm', label='Axis 5') 210 | plt.plot(plotted_values_A6, 'y', label='Axis 6') 211 | 212 | plt.pause(0.00001) 213 | count+=1 214 | 215 | # Resizing plot 216 | if(count+20 > xaxis_t0): 217 | xaxis_t0+=50 218 | plt.axis([0, xaxis_t0, -100, 100]) 219 | 220 | finally: 221 | # Close OPC UA client connection, remove subcsriptions, etc 222 | server.stop() 223 | -------------------------------------------------------------------------------- /opcua-server/opcua-server01.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Source code for an OPC UA server able to extract axis variables 3 | from a KUKA KR C4 robot controller and send them to an 4 | OPC UA client. 5 | 6 | Based on work by: 7 | - Massimiliano Fago (https://sourceforge.net/projects/openshowvar) 8 | - Mechatronics Lab at AAlesund University College 9 | (https://github.com/aauc-mechlab/JOpenShowVar) 10 | - Ahmad Saeed (https://github.com/akselov/kukavarproxy-msg-format) 11 | - Olivier Roulet-Dubonnet (https://github.com/FreeOpcUa) 12 | 13 | Author: Aksel Oevern 14 | NTNU 2018 15 | ''' 16 | 17 | import sys 18 | import socket 19 | sys.path.insert(0, "..") 20 | import time 21 | from opcua import ua, Server 22 | 23 | class KUKA(object): 24 | # Open socket 25 | # KukaVarProxy actively listens on TCP port 7000 26 | def __init__(self, TCP_IP): 27 | try: 28 | client.connect((TCP_IP, 7000)) 29 | except: 30 | self.error_list(1) 31 | 32 | # Sending messages on the KukaVarProxy message format: 33 | # Msg ID in HEX 2 bytes 34 | # Msg length in HEX 2 bytes 35 | # Read (0) or write (1) 1 byte 36 | # Variable name length in HEX 2 bytes 37 | # Variable name in ASCII # bytes 38 | # Variable value length in HEX 2 bytes 39 | # Variable value in ASCII # bytes 40 | def send (self, var, val, msgID): 41 | try: 42 | msg = bytearray() 43 | temp = bytearray() 44 | if val != "": 45 | val = str(val) 46 | msg.append((len(val) & 0xff00) >> 8) 47 | msg.append((len(val) & 0x00ff)) 48 | msg.extend(map(ord, val)) 49 | temp.append(bool(val)) 50 | temp.append(((len(var)) & 0xff00) >> 8) 51 | temp.append((len(var)) & 0x00ff) 52 | temp.extend(map(ord, var)) 53 | msg = temp + msg 54 | del temp[:] 55 | temp.append((msgID & 0xff00) >> 8) 56 | temp.append(msgID & 0x00ff) 57 | temp.append((len(msg) & 0xff00) >> 8) 58 | temp.append((len(msg) & 0x00ff)) 59 | msg = temp + msg 60 | except : 61 | self.error_list(2) 62 | try: 63 | client.send(msg) 64 | return client.recv(1024) 65 | except : 66 | self.error_list(1) 67 | 68 | # Get variables from KukaVarProxy response format 69 | def __get_var(self, msg): 70 | try: 71 | lsb = int( msg[5]) 72 | msb = int( msg[6]) 73 | lenValue = (lsb <<8 | msb) 74 | return str(msg [7: 7+lenValue],'utf-8') 75 | except: 76 | self.error_list(2) 77 | 78 | # Read variables from KukaVarProxy 79 | def read (self, var, msgID=0): 80 | try: 81 | return self.__get_var(self.send(var,"",msgID)) 82 | except : 83 | self.error_list(2) 84 | 85 | # Write variables to KukaVarProxy 86 | def write (self, var, val, msgID=0): 87 | try: 88 | if val != (""): 89 | return self.__get_var(self.send(var,val,msgID)) 90 | else: 91 | raise self.error_list(3) 92 | except : 93 | self.error_list(2) 94 | 95 | # Close socket 96 | def disconnect (self): 97 | client.close() 98 | 99 | # In case of error 100 | def error_list (self, ID): 101 | if ID == 1: 102 | print ("Network Error (tcp_error)") 103 | print ("Check your KRC's IP address on the network, and make sure kukaproxyvar is running.") 104 | self.disconnect() 105 | raise SystemExit 106 | elif ID == 2: 107 | print ("Python Error.") 108 | print ("Check the code and uncomment the lines related to your python version.") 109 | self.disconnect() 110 | raise SystemExit 111 | elif ID == 3: 112 | print ("Error in write() statement.") 113 | print ("Variable value is not defined.") 114 | 115 | if __name__ == "__main__": 116 | # Initialize OPC-UA Client connection 117 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 118 | 119 | # Setup robot object 120 | robot = KUKA('192.168.250.16') 121 | 122 | # Setup OPC-UA Server 123 | server = Server() 124 | server.set_endpoint("opc.tcp://192.168.250.200:50895") 125 | 126 | # Setup namespace 127 | uri = "http://examples.freeopcua.github.io" 128 | idx = server.register_namespace(uri) 129 | 130 | # Get objects node 131 | objects = server.get_objects_node() 132 | 133 | # Populating address space 134 | myObject = objects.add_object(idx, "KUKA_KR16_2") 135 | 136 | # Adding desired variables 137 | A1 = myObject.add_variable(idx, "A1", 6.7) 138 | A2 = myObject.add_variable(idx, "A2", 6.7) 139 | A3 = myObject.add_variable(idx, "A3", 6.7) 140 | A4 = myObject.add_variable(idx, "A4", 6.7) 141 | A5 = myObject.add_variable(idx, "A5", 6.7) 142 | A6 = myObject.add_variable(idx, "A6", 6.7) 143 | 144 | A1.set_writable() 145 | A2.set_writable() 146 | A3.set_writable() 147 | A4.set_writable() 148 | A5.set_writable() 149 | A6.set_writable() 150 | 151 | # Starting OPC-UA Server 152 | server.start() 153 | 154 | try: 155 | while(True): 156 | time.sleep(0.1) 157 | 158 | A1.set_value(robot.read("$AXIS_ACT.A1")) 159 | A2.set_value(robot.read("$AXIS_ACT.A2")) 160 | A3.set_value(robot.read("$AXIS_ACT.A3")) 161 | A4.set_value(robot.read("$AXIS_ACT.A4")) 162 | A5.set_value(robot.read("$AXIS_ACT.A5")) 163 | A6.set_value(robot.read("$AXIS_ACT.A6")) 164 | 165 | finally: 166 | # Close OPC UA client connection, remove subcsriptions, etc 167 | server.stop() 168 | -------------------------------------------------------------------------------- /opcua-server/opcua-server02.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Source code for an OPC UA server able to extract axis variables 3 | from a KUKA KR C4 robot controller and send them to an 4 | OPC UA client. 5 | 6 | Based on work by: 7 | - Massimiliano Fago (https://sourceforge.net/projects/openshowvar) 8 | - Mechatronics Lab at AAlesund University College 9 | (https://github.com/aauc-mechlab/JOpenShowVar) 10 | - Ahmad Saeed (https://github.com/akselov/kukavarproxy-msg-format) 11 | - Olivier Roulet-Dubonnet (https://github.com/FreeOpcUa) 12 | 13 | Author: Aksel Oevern 14 | NTNU 2018 15 | ''' 16 | 17 | import sys 18 | import socket 19 | sys.path.insert(0, "..") 20 | import time 21 | from opcua import ua, Server 22 | 23 | class KUKA(object): 24 | # Open socket 25 | # KukaVarProxy actively listens on TCP port 7000 26 | def __init__(self, TCP_IP): 27 | try: 28 | client.connect((TCP_IP, 7000)) 29 | except: 30 | self.error_list(1) 31 | 32 | # Sending messages on the KukaVarProxy message format: 33 | # Msg ID in HEX 2 bytes 34 | # Msg length in HEX 2 bytes 35 | # Read (0) or write (1) 1 byte 36 | # Variable name length in HEX 2 bytes 37 | # Variable name in ASCII # bytes 38 | # Variable value length in HEX 2 bytes 39 | # Variable value in ASCII # bytes 40 | def send (self, var, val, msgID): 41 | try: 42 | msg = bytearray() 43 | temp = bytearray() 44 | if val != "": 45 | val = str(val) 46 | msg.append((len(val) & 0xff00) >> 8) 47 | msg.append((len(val) & 0x00ff)) 48 | msg.extend(map(ord, val)) 49 | temp.append(bool(val)) 50 | temp.append(((len(var)) & 0xff00) >> 8) 51 | temp.append((len(var)) & 0x00ff) 52 | temp.extend(map(ord, var)) 53 | msg = temp + msg 54 | del temp[:] 55 | temp.append((msgID & 0xff00) >> 8) 56 | temp.append(msgID & 0x00ff) 57 | temp.append((len(msg) & 0xff00) >> 8) 58 | temp.append((len(msg) & 0x00ff)) 59 | msg = temp + msg 60 | except : 61 | self.error_list(2) 62 | try: 63 | client.send(msg) 64 | return client.recv(1024) 65 | except : 66 | self.error_list(1) 67 | 68 | # Get variables from KukaVarProxy response format 69 | def __get_var(self, msg): 70 | try: 71 | lsb = int( msg[5]) 72 | msb = int( msg[6]) 73 | lenValue = (lsb <<8 | msb) 74 | return str(msg [7: 7+lenValue],'utf-8') 75 | except: 76 | self.error_list(2) 77 | 78 | # Read variables from KukaVarProxy 79 | def read (self, var, msgID=0): 80 | try: 81 | return self.__get_var(self.send(var,"",msgID)) 82 | except : 83 | self.error_list(2) 84 | 85 | # Write variables to KukaVarProxy 86 | def write (self, var, val, msgID=0): 87 | try: 88 | if val != (""): 89 | return self.__get_var(self.send(var,val,msgID)) 90 | else: 91 | raise self.error_list(3) 92 | except : 93 | self.error_list(2) 94 | 95 | # Close socket 96 | def disconnect (self): 97 | client.close() 98 | 99 | # In case of error 100 | def error_list (self, ID): 101 | if ID == 1: 102 | print ("Network Error (tcp_error)") 103 | print ("Check your KRC's IP address on the network, and make sure kukaproxyvar is running.") 104 | self.disconnect() 105 | raise SystemExit 106 | elif ID == 2: 107 | print ("Python Error.") 108 | print ("Check the code and uncomment the lines related to your python version.") 109 | self.disconnect() 110 | raise SystemExit 111 | elif ID == 3: 112 | print ("Error in write() statement.") 113 | print ("Variable value is not defined.") 114 | 115 | if __name__ == "__main__": 116 | # Initialize OPC-UA Client connection 117 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 118 | 119 | # Setup robot object 120 | robot = KUKA('192.168.250.16') 121 | 122 | # Setup OPC-UA Server 123 | server = Server() 124 | server.set_endpoint("opc.tcp://192.168.250.200:50895") 125 | 126 | # Setup namespace 127 | uri = "http://examples.freeopcua.github.io" 128 | idx = server.register_namespace(uri) 129 | 130 | # Get objects node 131 | objects = server.get_objects_node() 132 | 133 | # Populating address space 134 | myObject = objects.add_object(idx, "KUKA_KR16_2") 135 | 136 | # Adding desired variables 137 | A1 = myObject.add_variable(idx, "A1", 6.7) 138 | A2 = myObject.add_variable(idx, "A2", 6.7) 139 | A3 = myObject.add_variable(idx, "A3", 6.7) 140 | A4 = myObject.add_variable(idx, "A4", 6.7) 141 | A5 = myObject.add_variable(idx, "A5", 6.7) 142 | A6 = myObject.add_variable(idx, "A6", 6.7) 143 | 144 | A1.set_writable() 145 | A2.set_writable() 146 | A3.set_writable() 147 | A4.set_writable() 148 | A5.set_writable() 149 | A6.set_writable() 150 | 151 | # Starting OPC-UA Server 152 | server.start() 153 | 154 | try: 155 | while(True): 156 | time.sleep(0.1) 157 | 158 | output = robot.read("$AXIS_ACT") 159 | output = output.replace(",", "") 160 | output_elements = output.split(" ") 161 | 162 | A1.set_value(output_elements[2]) 163 | A2.set_value(output_elements[4]) 164 | A3.set_value(output_elements[6]) 165 | A4.set_value(output_elements[8]) 166 | A5.set_value(output_elements[10]) 167 | A6.set_value(output_elements[12]) 168 | 169 | finally: 170 | # Close OPC UA client connection, remove subcsriptions, etc 171 | server.stop() 172 | -------------------------------------------------------------------------------- /pictures/Connected_Variables_VC_4.0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akselov/digital-twin-opcua/adc30f46466595a278f87f23a304a3630deca4da/pictures/Connected_Variables_VC_4.0.png -------------------------------------------------------------------------------- /pictures/InformationFlow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akselov/digital-twin-opcua/adc30f46466595a278f87f23a304a3630deca4da/pictures/InformationFlow.png -------------------------------------------------------------------------------- /pictures/Physical_&_digital_model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akselov/digital-twin-opcua/adc30f46466595a278f87f23a304a3630deca4da/pictures/Physical_&_digital_model.png -------------------------------------------------------------------------------- /pictures/VCmodel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akselov/digital-twin-opcua/adc30f46466595a278f87f23a304a3630deca4da/pictures/VCmodel.png -------------------------------------------------------------------------------- /pictures/gui_full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akselov/digital-twin-opcua/adc30f46466595a278f87f23a304a3630deca4da/pictures/gui_full.png -------------------------------------------------------------------------------- /rsi/RSIAxisCorrTestConfig2016v2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 192.168.1.198 4 | 49001 5 | ImFree 6 | FALSE 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /rsi/RSI_AxisCorr2016v2.src: -------------------------------------------------------------------------------- 1 | &ACCESS RVP 2 | &REL 6 3 | &PARAM TEMPLATE = C:\KRC\Roboter\Template\vorgabe 4 | &PARAM EDITMASK = * 5 | DEF RSI_AxisCorr2016v2( ) 6 | ; ============================================= 7 | ; 8 | ; RSI EXAMPLE: ETHERNET communication 9 | ; Realtime UDP data exchange with server application 10 | ; 11 | ; ============================================= 12 | 13 | ; Declaration of KRL variables 14 | DECL INT ret ; Return value for RSI commands 15 | DECL INT CONTID ; ContainerID 16 | 17 | ;FOLD INI 18 | ;FOLD BASISTECH INI 19 | GLOBAL INTERRUPT DECL 3 WHEN \$STOPMESS==TRUE DO IR_STOPM ( ) 20 | INTERRUPT ON 3 21 | BAS (#INITMOV,0 ) 22 | ;ENDFOLD (BASISTECH INI) 23 | ;FOLD USER INI 24 | ;Make your modifications here 25 | 26 | ;ENDFOLD (USER INI) 27 | ;ENDFOLD (INI) 28 | 29 | ; Move to start position 30 | PTP {A1 0, A2 -90, A3 90, A4 0, A5 90, A6 0} 31 | 32 | ; Create RSI Context 33 | ret = RSI_CREATE("RSIAxisCorrTest2016v2.rsi",CONTID,TRUE) 34 | IF (ret <> RSIOK) THEN 35 | HALT 36 | ENDIF 37 | 38 | ; Start RSI execution 39 | ret = RSI_ON(#ABSOLUTE) 40 | IF (ret <> RSIOK) THEN 41 | HALT 42 | ENDIF 43 | 44 | ; Sensor guided movement 45 | RSI_MOVECORR() 46 | 47 | ; Turn off RSI 48 | ret = RSI_OFF() 49 | IF (ret <> RSIOK) THEN 50 | HALT 51 | ENDIF 52 | 53 | PTP {A1 0, A2 -90, A3 90, A4 0, A5 90, A6 0} 54 | 55 | END 56 | -------------------------------------------------------------------------------- /rsi/rsi-opcua-server.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Source code for an OPC UA server able to extract axis variables 3 | from a KUKA KR C4 robot controller through RSI communication 4 | and send them to an OPC UA client. 5 | 6 | Based on work by: 7 | - Olivier Roulet-Dubonnet (https://github.com/FreeOpcUa) 8 | - Eren Sezener (https://github.com/akselov/kuka-rsi3-communicator) 9 | - Torstein Anderssen Myhre (https://github.com/torstem/examplecode-kukarsi-python) 10 | 11 | Author: Aksel Oevern 12 | NTNU 2018 13 | 14 | To be done: 15 | - Connection with rsi breaks down when joint corrections are to big 16 | ''' 17 | 18 | import socket 19 | import numpy 20 | import command 21 | import time 22 | import time_keeper 23 | from opcua import ua, Server 24 | 25 | tiden = time_keeper.time_keeper() 26 | 27 | def simple_joint_correction_command(from_kuka): 28 | # Axis Correction example (not used) 29 | #A1 = 10.0 * numpy.sin(tiden.get() / 10.0) 30 | 31 | joint_desired = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0] 32 | #joint_desired = [A1, 0.0, 0.0, 0.0, 0.0, 0.0] 33 | return command.joint_correction_command(from_kuka, joint_desired) 34 | 35 | if __name__ == "__main__": 36 | # Initialize OPC-UA Client connection 37 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 38 | 39 | # Setup OPC-UA Server 40 | server = Server() 41 | server.set_endpoint("opc.tcp://192.168.250.119:50895") 42 | 43 | # Setup namespace 44 | uri = "http://examples.freeopcua.github.io" 45 | idx = server.register_namespace(uri) 46 | 47 | # Get objects node 48 | objects = server.get_objects_node() 49 | 50 | # Populating address space 51 | myObject = objects.add_object(idx, "KUKA_KR16_2") 52 | 53 | # Adding desired variables 54 | A1 = myObject.add_variable(idx, "A1", 6.7) 55 | A2 = myObject.add_variable(idx, "A2", 6.7) 56 | A3 = myObject.add_variable(idx, "A3", 6.7) 57 | A4 = myObject.add_variable(idx, "A4", 6.7) 58 | A5 = myObject.add_variable(idx, "A5", 6.7) 59 | A6 = myObject.add_variable(idx, "A6", 6.7) 60 | 61 | A1.set_writable() 62 | A2.set_writable() 63 | A3.set_writable() 64 | A4.set_writable() 65 | A5.set_writable() 66 | A6.set_writable() 67 | 68 | # Starting OPC-UA Server 69 | server.start() 70 | 71 | # Setup RSI connection 72 | BUFFER_SIZE = 1024 73 | sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 74 | sock.bind(("192.168.1.198", 49001)) 75 | counter = 0 76 | 77 | try: 78 | while True: 79 | # Buffer size is 1024 bytes 80 | received_data, socket_of_krc = sock.recvfrom(BUFFER_SIZE) 81 | received_data = received_data.decode("utf-8") 82 | output_elements = received_data.split(' ') 83 | raw_axis_variables = output_elements[14:20] 84 | axis_variables = [] 85 | 86 | for raw_axis in raw_axis_variables: 87 | axis_variables.append(raw_axis.split('"')[1]) 88 | 89 | A1.set_value(axis_variables[0]) 90 | A2.set_value(axis_variables[1]) 91 | A3.set_value(axis_variables[2]) 92 | A4.set_value(axis_variables[3]) 93 | A5.set_value(axis_variables[4]) 94 | A6.set_value(axis_variables[5]) 95 | 96 | kuka_command = simple_joint_correction_command(received_data) 97 | reply = bytes(kuka_command, 'utf-8') 98 | sock.sendto(reply, socket_of_krc) 99 | 100 | finally: 101 | # Close OPC UA client connection, remove subcsriptions, etc 102 | server.stop() 103 | -------------------------------------------------------------------------------- /xml/KUKAVARPROXY_communication.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Source code for a KUKAVARPROXY communication module being used 3 | by the opcua-server-xml.py for communication with a KUKA KR C4 4 | robot controller. The module extracts axis variables from the 5 | robot controller. 6 | 7 | - Massimiliano Fago (https://sourceforge.net/projects/openshowvar) 8 | - Mechatronics Lab at AAlesund University College 9 | (https://github.com/aauc-mechlab/JOpenShowVar) 10 | - Ahmad Saeed (https://github.com/akselov/kukavarproxy-msg-format) 11 | 12 | Author: Aksel Oevern 13 | NTNU 2018 14 | ''' 15 | 16 | import socket 17 | import time 18 | 19 | # Initialize OPC-UA Client connection 20 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 21 | 22 | class KUKA(object): 23 | 24 | # Open socket 25 | # KukaVarProxy actively listens on TCP port 7000 26 | def __init__(self, TCP_IP): 27 | try: 28 | client.connect((TCP_IP, 7000)) 29 | except: 30 | self.error_list(1) 31 | 32 | # Sending messages on the KukaVarProxy message format: 33 | # Msg ID in HEX 2 bytes 34 | # Msg length in HEX 2 bytes 35 | # Read (0) or write (1) 1 byte 36 | # Variable name length in HEX 2 bytes 37 | # Variable name in ASCII # bytes 38 | # Variable value length in HEX 2 bytes 39 | # Variable value in ASCII # bytes 40 | def send (self, var, val, msgID): 41 | try: 42 | msg = bytearray() 43 | temp = bytearray() 44 | if val != "": 45 | val = str(val) 46 | msg.append((len(val) & 0xff00) >> 8) 47 | msg.append((len(val) & 0x00ff)) 48 | msg.extend(map(ord, val)) 49 | temp.append(bool(val)) 50 | temp.append(((len(var)) & 0xff00) >> 8) 51 | temp.append((len(var)) & 0x00ff) 52 | temp.extend(map(ord, var)) 53 | msg = temp + msg 54 | del temp[:] 55 | temp.append((msgID & 0xff00) >> 8) 56 | temp.append(msgID & 0x00ff) 57 | temp.append((len(msg) & 0xff00) >> 8) 58 | temp.append((len(msg) & 0x00ff)) 59 | msg = temp + msg 60 | except : 61 | self.error_list(2) 62 | try: 63 | client.send(msg) 64 | return client.recv(1024) 65 | except : 66 | self.error_list(1) 67 | 68 | # Get variables from KukaVarProxy response format 69 | def __get_var(self, msg): 70 | try: 71 | lsb = int( msg[5]) 72 | msb = int( msg[6]) 73 | lenValue = (lsb <<8 | msb) 74 | return str(msg [7: 7+lenValue],'utf-8') 75 | except: 76 | self.error_list(2) 77 | 78 | # Read variables from KukaVarProxy 79 | def read (self, var, msgID=0): 80 | try: 81 | return self.__get_var(self.send(var,"",msgID)) 82 | except : 83 | self.error_list(2) 84 | 85 | # Write variables to KukaVarProxy 86 | def write (self, var, val, msgID=0): 87 | try: 88 | if val != (""): return self.__get_var(self.send(var,val,msgID)) 89 | else: raise self.error_list(3) 90 | except : 91 | self.error_list(2) 92 | 93 | # Close socket 94 | def disconnect (self): 95 | client.close() 96 | 97 | # In case of error 98 | def error_list (self, ID): 99 | if ID == 1: 100 | print ("Network Error (tcp_error)") 101 | print ("Check your KRC's IP address on the network, and make sure kukaproxyvar is running.") 102 | self.disconnect() 103 | raise SystemExit 104 | elif ID == 2: 105 | print ("Python Error.") 106 | print ("Check the code and uncomment the lines related to your python version.") 107 | self.disconnect() 108 | raise SystemExit 109 | elif ID == 3: 110 | print ("Error in write() statement.") 111 | print ("Variable value is not defined.") 112 | 113 | def run(variables_axis, ip_adress): 114 | # Setup robot object 115 | robot = KUKA(ip_adress.get_value()) 116 | print("KUKAVARPROXY communication running successfully \nObject's IP adress:", ip_adress.get_value()) 117 | 118 | while True: 119 | time.sleep(0.01) 120 | 121 | output = robot.read("$AXIS_ACT") 122 | output = output.replace(",", "") 123 | output_elements = output.split(" ") 124 | 125 | i = 0 126 | for axis in variables_axis: 127 | axis.set_value(output_elements[2+i]) 128 | i+=2 129 | -------------------------------------------------------------------------------- /xml/KUKA_KR120_object.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | i=1 16 | i=11 17 | i=12 18 | i=35 19 | i=40 20 | i=46 21 | i=47 22 | 23 | 24 | KUKA_KR120_1 25 | The base type for all object nodes. 26 | 27 | i=85 28 | i=58 29 | i=30006 30 | i=30007 31 | i=30008 32 | i=30009 33 | i=30010 34 | i=30011 35 | i=30012 36 | i=30013 37 | i=30016 38 | 39 | 40 | 41 | KUKAVARPROXY 42 | KUKAVARPROXY 43 | 44 | i=30001 45 | i=68 46 | 47 | 48 | false 49 | 50 | 51 | 52 | RSI 53 | RSI 54 | 55 | i=30001 56 | i=68 57 | 58 | 59 | false 60 | 61 | 62 | 63 | A1 64 | A1 65 | 66 | i=30001 67 | i=63 68 | 69 | 70 | 9.99 71 | 72 | 73 | 74 | A2 75 | A2 76 | 77 | i=30001 78 | i=63 79 | 80 | 81 | 9.99 82 | 83 | 84 | 85 | A3 86 | A3 87 | 88 | i=30001 89 | i=63 90 | 91 | 92 | 9.99 93 | 94 | 95 | 96 | A4 97 | A4 98 | 99 | i=30001 100 | i=63 101 | 102 | 103 | 9.99 104 | 105 | 106 | 107 | A5 108 | A5 109 | 110 | i=30001 111 | i=63 112 | 113 | 114 | 9.99 115 | 116 | 117 | 118 | A6 119 | A6 120 | 121 | i=30001 122 | i=63 123 | 124 | 125 | 9.99 126 | 127 | 128 | 129 | IP 130 | IP 131 | 132 | i=30001 133 | i=68 134 | 135 | 136 | 192.168.250.120 137 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /xml/KUKA_KR16_2_object.xml: -------------------------------------------------------------------------------- 1 | 12 | 13 | 14 | 15 | 16 | 17 | i=1 18 | i=11 19 | i=12 20 | i=35 21 | i=40 22 | i=46 23 | i=47 24 | 25 | 26 | KUKA_KR16_2 27 | The base type for all object nodes. 28 | 29 | i=85 30 | i=58 31 | i=20006 32 | i=20007 33 | i=20008 34 | i=20009 35 | i=20010 36 | i=20011 37 | i=20012 38 | i=20013 39 | i=20016 40 | 41 | 42 | 43 | KUKAVARPROXY 44 | KUKAVARPROXY 45 | 46 | i=20001 47 | i=68 48 | 49 | 50 | false 51 | 52 | 53 | 54 | RSI 55 | RSI 56 | 57 | i=20001 58 | i=68 59 | 60 | 61 | false 62 | 63 | 64 | 65 | A1 66 | A1 67 | 68 | i=20001 69 | i=63 70 | 71 | 72 | 9.99 73 | 74 | 75 | 76 | A2 77 | A2 78 | 79 | i=20001 80 | i=63 81 | 82 | 83 | 9.99 84 | 85 | 86 | 87 | A3 88 | A3 89 | 90 | i=20001 91 | i=63 92 | 93 | 94 | 9.99 95 | 96 | 97 | 98 | A4 99 | A4 100 | 101 | i=20001 102 | i=63 103 | 104 | 105 | 9.99 106 | 107 | 108 | 109 | A5 110 | A5 111 | 112 | i=20001 113 | i=63 114 | 115 | 116 | 9.99 117 | 118 | 119 | 120 | A6 121 | A6 122 | 123 | i=20001 124 | i=63 125 | 126 | 127 | 9.99 128 | 129 | 130 | 131 | IP 132 | IP 133 | 134 | i=20001 135 | i=68 136 | 137 | 138 | 192.168.250.16 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /xml/KUKA_KR5_object.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | i=1 16 | i=11 17 | i=12 18 | i=35 19 | i=40 20 | i=46 21 | i=47 22 | 23 | 24 | KUKA_KR16_2 25 | The base type for all object nodes. 26 | 27 | i=85 28 | i=58 29 | i=40006 30 | i=40007 31 | i=40008 32 | i=40009 33 | i=40010 34 | i=40011 35 | i=40012 36 | i=40013 37 | i=40016 38 | 39 | 40 | 41 | KUKAVARPROXY 42 | KUKAVARPROXY 43 | 44 | i=40001 45 | i=68 46 | 47 | 48 | false 49 | 50 | 51 | 52 | RSI 53 | RSI 54 | 55 | i=40001 56 | i=68 57 | 58 | 59 | false 60 | 61 | 62 | 63 | A1 64 | A1 65 | 66 | i=40001 67 | i=63 68 | 69 | 70 | 9.99 71 | 72 | 73 | 74 | A2 75 | A2 76 | 77 | i=40001 78 | i=63 79 | 80 | 81 | 9.99 82 | 83 | 84 | 85 | A3 86 | A3 87 | 88 | i=40001 89 | i=63 90 | 91 | 92 | 9.99 93 | 94 | 95 | 96 | A4 97 | A4 98 | 99 | i=40001 100 | i=63 101 | 102 | 103 | 9.99 104 | 105 | 106 | 107 | A5 108 | A5 109 | 110 | i=40001 111 | i=63 112 | 113 | 114 | 9.99 115 | 116 | 117 | 118 | A6 119 | A6 120 | 121 | i=40001 122 | i=63 123 | 124 | 125 | 9.99 126 | 127 | 128 | 129 | IP 130 | IP 131 | 132 | i=40001 133 | i=68 134 | 135 | 136 | 192.168.250.5 137 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /xml/opcua-server-xml.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Source code for an OPC UA server able to create a custom OPC UA 3 | object from specifications in a XML-file, estract axis variables 4 | from a KUKA KR C4 robot controller and send them to an OPC UA client. 5 | 6 | Based on work by: 7 | - Massimiliano Fago (https://sourceforge.net/projects/openshowvar) 8 | - Mechatronics Lab at AAlesund University College 9 | (https://github.com/aauc-mechlab/JOpenShowVar) 10 | - Ahmad Saeed (https://github.com/akselov/kukavarproxy-msg-format) 11 | - Olivier Roulet-Dubonnet (https://github.com/FreeOpcUa) 12 | 13 | To be done: 14 | - Include RSI control module 15 | 16 | Author: Aksel Oevern 17 | NTNU 2018 18 | ''' 19 | 20 | import sys 21 | sys.path.insert(0, "..") 22 | import time 23 | import KUKAVARPROXY_communication 24 | from opcua import ua, Server 25 | 26 | if __name__ == "__main__": 27 | # Setup OPC-UA Server 28 | server = Server() 29 | server.set_endpoint("opc.tcp://192.168.250.200:50895") 30 | 31 | # Setup namespace 32 | uri = "http://examples.freeopcua.github.io" 33 | idx = server.register_namespace(uri) 34 | 35 | # Get objects node 36 | objects = server.get_objects_node() 37 | 38 | # Import customobject type 39 | server.import_xml('KUKA_KR16_2_object.xml') 40 | 41 | # Check if client wants communication over KUKAVARPROXY or RSI 42 | kuka_object = objects.get_child("0:KUKA_KR16_2") 43 | ip_adress = kuka_object.get_child("0:IP") 44 | variable_kukavarproxy = kuka_object.get_child("0:KUKAVARPROXY") 45 | variable_rsi = kuka_object.get_child("0:RSI") 46 | 47 | # Extracting axis variables and removing KUKAVARPROXU/RSI configuration variables 48 | variables_all = kuka_object.get_children() 49 | 50 | for variable in variables_all: 51 | variable.set_writable() 52 | 53 | # Removing configuration properties 54 | variables_all.remove(ip_adress) 55 | variables_all.remove(variable_kukavarproxy) 56 | variables_all.remove(variable_rsi) 57 | variables_axis = variables_all 58 | 59 | # Starting OPC-UA Server 60 | server.start() 61 | 62 | try: 63 | print("Select KUKAVARPROXY or RSI communication configuration in OPC UA Client") 64 | while True: 65 | time.sleep(0.1) 66 | 67 | # Check for client preference KUKAVARPROXY/RSI communication 68 | if(variable_kukavarproxy.get_value() and variable_rsi.get_value()): 69 | raise ValueError("KUKAVARPROXY and RSI can not both be selected") 70 | SystemExit 71 | 72 | if(variable_kukavarproxy.get_value()): 73 | print("Launching KUKAVARPROXY communication") 74 | KUKAVARPROXY_communication.run(variables_axis, ip_adress) 75 | break 76 | 77 | if(variable_rsi.get_value()): 78 | print("Launching RSI communication") 79 | #Run RSI communication module 80 | 81 | finally: 82 | # Close OPC UA client connection, remove subcsriptions, etc 83 | server.stop() 84 | --------------------------------------------------------------------------------