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].
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].
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
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], x_test[i], x_test[i], x_test[i], x_test[i], x_test[i]] ToBePredicted = array([b]) Prediction = model.predict(ToBePredicted) a = [Prediction, Prediction, Prediction, Prediction, Prediction, Prediction] # 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 ?