Good morning everyone,
I’ll try to briefly explain the context and then the problem I’m facing:
Context: I am using and testing a collaborative Robot. This Robot has been provided to me with a library in python that allows to acquire signals from the robot (currents, velocity, positions, I/O etc) and to command it, in joint and end-effector (EE) coordinates. There are also available the functions of Direct and Inverse Kinematics (DK and IK).
For my curiosity, I was interested in generating a trajectory (in end-effector coordinates) in order to move it within a conical area [I attach a link to the video that shows the movement in question].
LINK: https://www.youtube.com/watch?v=CExtMfvRabo
From the robot, moreover, it is possible to save the .csv file containing the trajectories, in joint coordinates, of the single joints.
Initially, not knowing the “shape” that should have the trajectory (in end-effector coordinates) of the movement that I was interested in reproducing, I was able, manually moving the robot in gravity compensation mode, to acquire the trajectories of the individual joints. At this point, using the Direct Kinematics algorithm, I obtained the movement of the consequent end-effector [I attach photos of 2 3D graphs: the first in which I plot the 3 coordinates x,y,z and the second, in which I plot roll, pitch, yaw].
End Effector Angular Displacement
End Effector Position Displacement
Here the problem was born.
Problem: out of curiosity, I tried to use the Inverse Kinematics algorithm on the points obtained from the DK and the algorithm returned the error: “Singular Trajectory”. But the robot was able to move according to that trajectory, the problem should be in the calculation of the IK, which probably finds multiple/infinite solutions.
To overcome this limitation I used a Neural Network developed in Python using Tensorflow (Keras) to try to approximate the IK. I will preface this by saying that I have never used Keras or Tensorflow, so I may have made some conceptual errors. I have consulted the API of Keras and also the guide proposed in this link
LINK: https://machinelearningmastery.com/deep-learning-models-for-multi-output-regression/
In my PC I use:
- Visual Studio Code for programming in python;
- python 3.9.5
- Keras 2.6.0;
I thought of the neural network this way: 6 input nodes (corresponding to the 6 coordinates of the end-effector) and 6 output nodes (the 6 coordinates of the joints). The training set consists of a .csv file containing the 6 coordinates of the end-effector computed via the DK run on a .csv file containing the trajectories of the 6 joints. The file containing the joint coordinates is the Label file.
Below I attach the code of the network implementation.
from numpy import loadtxt
import numpy as np
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Dense
import tensorflow as tf
from numpy import array
# Model definition
def get_model(I_N_L_1, I_N_L_2, I_N_L_3, I_N_L_4, I_N_L_5 ,n_inputs, n_outputs):
model = Sequential()
model.add(Dense(I_N_L_1, input_dim=n_inputs, kernel_initializer='he_uniform', activation='relu'))
model.add(Dense(I_N_L_2, activation='relu'))
model.add(Dense(I_N_L_3, activation='relu'))
model.add(Dense(I_N_L_4, activation='relu'))
model.add(Dense(I_N_L_5, activation='relu'))
model.add(Dense(n_outputs))
model.compile(loss='mae', optimizer='adam', metrics=["mae"])
return model
# Load Training set csv
dataset_EF = loadtxt('WeldingProve.csv', delimiter=',')
x_train = dataset_EF[0:1700,0:6]
print('shape: ',x_train.shape)
# Load Label set csv
dataset_joints = loadtxt('EF_from_WeldingProve.csv', delimiter=',')
y_train = dataset_joints[0:1700,0:6]
print('shape: ',y_train.shape)
# Test set definition
x_test = dataset_EF[1701:,0:6]
print('shape: ',x_test.shape)
# Label of the test set definition
y_test = dataset_joints[1701:,0:6]
print('shape: ',y_test.shape)
# Number of nodes in the hidden layers
I_N_L_1 = 192
I_N_L_2 = 36
I_N_L_3 = 6
I_N_L_4 = 36
I_N_L_5 = 192
# Number of nodes in the input and output layers
n_inputs = 6
n_outputs = 6
# calling the "get_model" function
model = get_model(I_N_L_1, I_N_L_2, I_N_L_3, I_N_L_4, I_N_L_5 ,n_inputs, n_outputs)
es = tf.keras.callbacks.EarlyStopping(monitor='loss', patience=5)
# fit model
model.fit(x_train, y_train, verbose=1, epochs=600)
# saving the model
model.save("Test_Model.h5")
# Testing procedure
pred = []
# Computing the Prediction on the Test Set
for i in range(len(x_test)-1):
b = [x_test[i][0], x_test[i][1], x_test[i][2], x_test[i][3], x_test[i][4], x_test[i][5]]
ToBePredicted = array([b])
Prediction = model.predict(ToBePredicted)
a = [Prediction[0][0], Prediction[0][1], Prediction[0][2], Prediction[0][3], Prediction[0][4], Prediction[0][5]]
# Computing the mean vector of the error for each predicted joint trajectory
average_vector = []
sum = 0
average = 0
for j in range(6): # colonne
for i in range(len(y_test)-1): #righe
sum = sum + (pred[i][j] - y_test[i][j])
average = sum/len(y_test)
average_vector.append(average)
average = 0
sum = 0
print('average_vector: ', average_vector)
# Computing the standard deviation vector of the error for each predicted joint trajectory
sum = 0
std_vector = []
for j in range(6): # colonne
for i in range(len(y_test)-1): #righe
sum = sum + ((pred[i][j] - y_test[i][j]) - average_vector[j])**2
std = (sum/len(y_test))**(0.5)
std_vector.append(std)
std = 0
sum = 0
print('std_vector: ', std_vector)
My questions are the following:
-
once I have trained the neural network, even using a very large training set, I get predictions that are not good. Can you suggest me how to improve these predictions, perhaps going to act on the parameters of the network,
-
Is it necessary to pre-process the training data and its labels? If yes, which technique should I apply?
-
Trying to change the number of nodes in the various layers of the network, I saw that the performance changes, even a lot. Do you have advice on the “shape” to give to the network ?
-
Are there any other solutions that can be used to estimate the IK of the robot ?