How can I retrieve force data from a cobot using Python?

Hello everyone,

I am currently working on a project where I want to read the position and force data of a UR robot (Universal Robots) using Python. I’ve encountered a few challenges and would appreciate any support.

My progress so far:

  • The connection to the cobot is established without any issues.
  • I am also successfully receiving the position data.
  • I am receiving force data as well, but they only read as 0 (even in the raw data), so I assume that there might be an issue with the cobot sending these values.

Additionally, I would like to output the data into a table (Excel) after each run.

Thank you in advance for your help!

import datetime
import time
import sys
import socket
import struct

# Connection parameters for the robot
HOST = '192........'  # IP of the UR robot
PORT = 30012            # Port for data transmission (read-only)

# Data format for unpacking
uIntFmt = '>I'          # Unsigned int (big-endian)
doubleFmt = 'd'         # Double (8 Bytes)

# Counter variable for failed connection attempts
vCountDataNull = 0
vConnectedToServer = False

# Establish connection to the server
while True:
    time.sleep(0.5)  # Wait time to reduce network load
    
    if not vConnectedToServer:
        # Establish socket connection to the robot
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        try:
            s.connect((HOST, PORT))
            vConnectedToServer = True
            print("Connection established")
        except Exception as e:
            print(f"Connection error: {e}")
            vCountDataNull += 1
            if vCountDataNull > 5:
                sys.exit("Connection attempts exceeded!")
            continue
    
    try:
        # Receive data packet from the robot
        data = s.recv(4096)

        if not data:
            print("No data received, retrying.")
            continue  # No data received, try again
        
        # Extract packet length and robot message type
        vPackLen = struct.unpack(uIntFmt, data[0:4])[0]
        vRobotMsgType = data[4]

        # Remove header part and extract actual data
        data = data[5:vPackLen]
        vLenData = len(data)

        # If message type is 16 (data packet), extract the corresponding data
        if vRobotMsgType == 16:
            vDataPack = []  # List for data packets
            iDataLoop = 0   # Counter for the loop

            while len(data) > 0:
                # Extract subpacket length and type
                vSubPackLen = struct.unpack(uIntFmt, data[0:4])[0]
                vSubPackType = data[4]

                # Store the subpacket in the list
                vDataPack.append([vSubPackType, data[5:vSubPackLen]])

                # Remove processed data
                data = data[vSubPackLen:]

                iDataLoop += 1

            # Process the received packets
            for vPackType in vDataPack:
                match vPackType[0]:
                    case 4:  # Cartesian position (TCP)
                        print('Cartesian information:')
                        PosX = struct.unpack('>d', vPackType[1][0:8])[0]
                        PosY = struct.unpack('>d', vPackType[1][8:16])[0]
                        PosZ = struct.unpack('>d', vPackType[1][16:24])[0]
                        print(f'PosX: {PosX}')
                        print(f'PosY: {PosY}')
                        print(f'PosZ: {PosZ}')
                        print('')

                    case 7:  # Force data (Force mode)
                        print('Force information:')
                        # KraftX = struct.unpack('>d', vPackType[1][0:8])[0]
                        # KraftY = struct.unpack('>d', vPackType[1][8:16])[0]
                        # KraftZ = struct.unpack('>d', vPackType[1][16:24])[0]
                        KraftX = struct.unpack(doubleFmt, vPackType[1][0:8])[0]
                        KraftY = struct.unpack(doubleFmt, vPackType[1][8:16])[0]
                        KraftZ = struct.unpack(doubleFmt, vPackType[1][16:24])[0]
                        print(f'Force in X: {KraftX}')
                        print(f'Force in Y: {KraftY}')
                        print(f'Force in Z: {KraftZ}')

    except Exception as e:
        print(f"Error receiving data: {e}")
        vConnectedToServer = False
        s.close()

I didn’t even know there is a port 30012
What model is it?
Can you see the force values on the robot side?

to retrieve force data from a cobot using oython, you typically need to use the Robot Operating System (ROS) or the specific API provided by the cobot manufacturer. For example, with UR robots (Universal Robots), you can use the URScript or pyUniversalRobot library to interface with the robot and retrieve force/torque data from the sensors. If your cobot supports EtherCAT or TCP/IP, you might also use a library like pyModbus or socket for communication.