All Collections
xArm-Python/C++ SDK
How to get the joint current/torque data of the UFACTORY xArm robot
How to get the joint current/torque data of the UFACTORY xArm robot
W
Written by Wang Daniel
Updated over a week ago

Examples are valid for:

UFACTORY xArm Studio version: ≥ 1.6.0
UFACTORY xArm Firmware version: ≥ 1.6.0
UFACTORY xArm Python-SDK: ≥ 1.6.0

UFACTORYxArm C++-SDK: 1.6.0

When the robotic arm executes the Blockly example below, execute the Python example of Appendix 1 or C++ example of Appendix 2 to get the joint torque data/joint current data of the robotic arm. It connects to controller port 30003 to get data reports at 100Hz.

Blockly Example

Typical joint torque diagram(joint 3)

Typical joint current diagram(joint 3)

Appendix-1

When you want to get the joint torque data, please download get_joint_torque.py

When you want to get the joint current data, please download get_joint_current.py


You can set the type of data obtained through the interface set_report_tau_or_i()

When you want to get the joint torque data, unit: N·m :

arm.set_report_tau_or_i(tau_or_i=0)

When you want to get the joint current data, unit: A :

arm.set_report_tau_or_i(tau_or_i=1)

The following example is an example of obtaining joint torque data.

import socket
import struct
import os
import sys
import time

sys.path.append(os.path.join(os.path.dirname(__file__), '../../..'))

from xarm.wrapper import XArmAPI
arm = XArmAPI('192.168.1.106', debug=True)

def bytes_to_fp32(bytes_data, is_big_endian=False):
"""
bytes to float
:param bytes_data: bytes
:param is_big_endian: is big endian or not,default is False.
:return: fp32
"""
return struct.unpack('>f' if is_big_endian else '<f', bytes_data)[0]

def bytes_to_fp32_list(bytes_data, n=0, is_big_endian=False):
"""
bytes to float list
:param bytes_data: bytes
:param n: quantity of parameters need to be converted,default is 0,all bytes converted.
:param is_big_endian: is big endian or not,default is False.
:return: float list
"""
ret = []
count = n if n > 0 else len(bytes_data) // 4
for i in range(count):
ret.append(bytes_to_fp32(bytes_data[i * 4: i * 4 + 4], is_big_endian))
return ret

def bytes_to_u32(data):
data_u32 = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]
return data_u32

robot_ip = '192.168.1.106' # IP of controller
robot_port = 30003 # Port of controller

# create socket to connect controller
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setblocking(True)
sock.settimeout(1)
sock.connect((robot_ip, robot_port))

arm.set_report_tau_or_i(tau_or_i=0)

while True:
data = sock.recv(4)
length = bytes_to_u32(data)
data += sock.recv(length - 4)
joint_data = bytes_to_fp32_list(data[59:87]) #The acquired data is the data from J1 to J7
print(joint_data)

Appendix-2

#include <sys/types.h>

#include <sys/socket.h>
#include <arpa/inet.h>
#include "xarm/wrapper/xarm_api.h"

int connect_remote_server(const char *server_ip, int port_num)
{
struct sockaddr_in server_addr;
int client_sockfd = socket(AF_INET, SOCK_STREAM, 0);
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(server_ip);
server_addr.sin_port = htons(port_num);
if(connect(client_sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)))
{
fprintf(stderr, "Error connecting remote server!\n");
close(client_sockfd);
return -1;
}
return client_sockfd;
}

// Run Example: $ ./xArm_report_30003 192.168.1.227 1
// Use "Ctrl-C" to terminate
int main(int argc, char** argv)
{
// PAY ATTENTION to this notice
fprintf(stderr, "\nMake sure robot is already ENABLED! Firmware version >= 1.5.2!\n\n");
if(argc!=3)
{
fprintf(stderr, "[Usage: ] argument 1: robot ip address (e.g. 192.168.1.227), argument 2: 0 for estimated torque report, 1 for actual motor current report\n");
return -1;
}
// connect to xArm control port
XArmAPI *arm = new XArmAPI(argv[1]);
sleep_milliseconds(500);
int ret = 0;
std::string report_str;
if (arm->is_connected()) {
switch(atoi(argv[2]))
{
case 0:
ret = arm->set_report_tau_or_i(0);
report_str = "estimated joint torques:\n";
break;
case 1:
ret = arm->set_report_tau_or_i(1);
report_str = "feedback motor currents:\n";
break;
default:
fprintf(stderr, "[Error: ] Invalid argument 2, 0 for estimated torque report, 1 for actual motor current report\n");
arm->disconnect();
return -1;
}
arm->disconnect();
unsigned char recv_chars[128] = {0};
float data[7] = {0};
int client_sock = connect_remote_server(argv[1], 30003);
if(client_sock!=-1)
{
while(true)
{
ret = recv(client_sock, recv_chars, 87, 0);
if(ret<0)
break;
hex_to_nfp32(&recv_chars[59], data, 7);
fprintf(stderr, "%s", report_str.c_str());
for(int i=0; i<7; i++)
fprintf(stderr, "%f\t", data[i]);
fprintf(stderr, "\n" );
sleep_milliseconds(2);
}
}
else
{
fprintf(stderr, "Please check the robot connection!\n");
return -1;
}
}
return 0;
}
Did this answer your question?