SUMMER PROJECT
Inverse Kinematics using Neural Networks
We wish to perform the inverse kinematics of the following robot manipulator with three planar links using
neural networks. The input angular positions of each link for a given output position is very difficult to figure
using normal algebraic analysis. Hence, we use neural networks which can make an approximate assumption of
the complex function of these angular positions. More data we feed into our model more accurate results we
will be able to achieve. The following figure shows the robot manipulator that we have selected.
Figure 1
First thing we require is training data for the neural network which can be obtained by doing the normal
kinematic analysis of the manipulator. The important concept which is essential for forward kinematics are the
concepts of Denavit-Hartenberg (DH) Convention and Transformation Matrix.
Denavit-Hartenberg (DH) Convention and Transformation Matrix
The Denavit-Hartenberg (DH) convention is a standardized method to represent the transformations between
adjacent links of a robotic manipulator. The DH parameters define the relative position and orientation of each
link in terms of four parameters: θ, d, a, and α.
DH Parameters
1. 𝜃𝑖 : Joint angle- This is the angle between the 𝑋𝑖−1 and 𝑋𝑖 axes measured around the 𝑍𝑖−1 axis.
2. 𝑑𝑖 : Link offset- This is the distance between the 𝑋𝑖−1 and 𝑋𝑖 axes measured along the 𝑍𝑖−1 axis.
3. 𝑎𝑖 : Link length- This is the distance between the 𝑍𝑖−1 and 𝑍𝑖 axes measured along the 𝑋𝑖 axis.
1
4. 𝜃𝑖 : Link twist- This is the angle between the 𝑍𝑖−1 and 𝑍𝑖 axes measured around the 𝑋𝑖 axis.
DH Transformation Matrix
The transformation matrix 𝐴𝑖 from frame (i-1) to frame (i) is given by:
cos(𝜃𝑖 ) − 𝑠𝑖𝑛(𝜃𝑖 )cos(𝛼𝑖 ) sin(𝜃𝑖 )sin(𝛼𝑖 ) 𝑎𝑖 𝑐𝑜𝑠(𝜃𝑖 )
𝑠𝑖𝑛(𝜃𝑖 ) 𝑐𝑜𝑠(𝜃𝑖 ) cos(𝛼𝑖 ) − 𝑐𝑜𝑠(𝜃𝑖 )sin(𝛼𝑖 ) 𝑎𝑖 𝑠𝑖𝑛(𝜃𝑖 )
𝐴𝑖 = [ ]
0 sin(𝛼𝑖 ) cos(𝛼𝑖 ) 𝑑𝑖
0 0 0 1
Now lets apply the DH convention and transformations to our manipulator shown in the figure 1 above.
Forward Kinematics of a Three-Link Planar Manipulator
The forward kinematics equations for a four-link planar robotic arm using Denavit-Hartenberg (DH) parameters
are explored below. The manipulator has four revolute joints, with each link assumed to be of length 1 unit. The
goal is to determine the position and orientation of the end-effector based on the given joint angles. The link
twist and link offset are all assumed to be 0 since the manipulator with its three links is completely planar in
nature. The summary table of DH parameters are shown below.
Link a (Link Length) α (Link Twist) d (Link Offset) θ (Joint Angle)
1 1 0 0 θ₁
2 1 0 0 θ₂
3 1 0 0 θ₃
Transformation Matrices
The transformation matrix for each link (i) using the DH parameters is given by:
cos(𝜃𝑖 ) − 𝑠𝑖𝑛(𝜃𝑖 ) 0 𝑎𝑖 𝑐𝑜𝑠(𝜃𝑖 )
𝑠𝑖𝑛(𝜃𝑖 ) 𝑐𝑜𝑠(𝜃𝑖 ) 0 𝑎𝑖 𝑠𝑖𝑛(𝜃𝑖 )
𝐴𝑖 = [ ]
0 0 1 𝑑𝑖
0 0 0 1
For each link, substituting the specific DH parameters yields the following transformation matrices:
cos(𝜃1 ) − 𝑠𝑖𝑛(𝜃1 ) 0 𝑎1 𝑐𝑜𝑠(𝜃1 )
𝑠𝑖𝑛(𝜃1 ) 𝑐𝑜𝑠(𝜃1 ) 0 𝑎1 𝑠𝑖𝑛(𝜃1 )
𝐴1 = [ ]
0 0 1 𝑑1
0 0 0 1
2
cos(𝜃2 ) − 𝑠𝑖𝑛(𝜃2 ) 0 𝑎2 𝑐𝑜𝑠(𝜃2 )
𝑠𝑖𝑛(𝜃2 ) 𝑐𝑜𝑠(𝜃2 ) 0 𝑎2 𝑠𝑖𝑛(𝜃2 )
𝐴2 = [ ]
0 0 1 𝑑2
0 0 0 1
cos(𝜃3 ) − 𝑠𝑖𝑛(𝜃3 ) 0 𝑎3 𝑐𝑜𝑠(𝜃3 )
𝑠𝑖𝑛(𝜃3 ) 𝑐𝑜𝑠(𝜃3 ) 0 𝑎3 𝑠𝑖𝑛(𝜃3 )
𝐴3 = [ ]
0 0 1 𝑑3
0 0 0 1
Overall Transformation Matrix
The overall transformation matrix from the base frame to the end-effector frame 𝑇3 is the product of the
individual transformation matrices:
𝑇3 = 𝐴1 𝐴2 𝐴3
Computing the matrix multiplication gives:
cos(𝜃1 + 𝜃2 + 𝜃3 ) − 𝑠𝑖𝑛(𝜃1 + 𝜃2 + 𝜃3 ) 0 𝑥
𝑠𝑖𝑛(𝜃1 + 𝜃2 + 𝜃3 ) 𝑐𝑜𝑠(𝜃1 + 𝜃2 + 𝜃3 ) 0 𝑦
𝑇3 = [ ]
0 0 1 𝑑3
0 0 0 1
Where:
x and y are the positions of the end-effector, which can be found by summing the x and y contributions from
each transformation matrix.
The final equations for the end-effector position (x, y) are:
End-Effector Position and Orientation
x = cos(θ1) + cos(θ1 + θ2) + cos(θ1 + θ2 + θ3) + cos(θ1 + θ2 + θ3 + θ4)
y = sin(θ1) + sin(θ1 + θ2) + sin(θ1 + θ2 + θ3) + sin(θ1 + θ2 + θ3 + θ4)
Now using this knowledge we can generate training data necessary for training the neural network. This neural
network, with proper training data and after running sufficient number of epochs will be able to approximate
the inverse kinematic equations which are difficult to derive analytically.
Python Code
Importing necessary libraries
import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from tensorflow.keras.models import Sequential
3
from tensorflow.keras.layers import Dense, Dropout
This piece of code installs all the necessary python libraries that we use for training the neural network.
Generating the training data
# Define the range of angles in degrees
angle_range = np.arange(0, 360, 6)
# Generate all possible combinations of θ1, θ2, θ3
data = np.array(np.meshgrid(angle_range, angle_range, angle_range)).T.reshape(-1,
3)
# Create a DataFrame with columns for θ1, θ2, θ3
df = pd.DataFrame(data, columns=['θ1', 'θ2', 'θ3'])
# Convert angles from degrees to radians for trigonometric calculations
df_rad = np.deg2rad(df)
# Calculate x and y using the given formulas
df['x'] = (np.cos(df_rad['θ1']) +
np.cos(df_rad['θ1'] + df_rad['θ2']) +
np.cos(df_rad['θ1'] + df_rad['θ2'] + df_rad['θ3']))
df['y'] = (np.sin(df_rad['θ1']) +
np.sin(df_rad['θ1'] + df_rad['θ2']) +
np.sin(df_rad['θ1'] + df_rad['θ2'] + df_rad['θ3']))
df.head()
Here the main features and output are generated and transferred into a dataframe named ‘df’. Totally 603
samples are generated. The description of ‘df’ is as follows
Adding additional features to the dataframe
# Additional features based on trigonometric components
df['cos_theta1'] = np.cos(df_rad['θ1'])
df['sin_theta1'] = np.sin(df_rad['θ1'])
df['cos_theta2'] = np.cos(df_rad['θ2'])
df['sin_theta2'] = np.sin(df_rad['θ2'])
df['cos_theta3'] = np.cos(df_rad['θ3'])
4
df['sin_theta3'] = np.sin(df_rad['θ3'])
# Combined features
df['cos_theta1_plus_theta2'] = np.cos(df_rad['θ1'] + df_rad['θ2'])
df['sin_theta1_plus_theta2'] = np.sin(df_rad['θ1'] + df_rad['θ2'])
# Calculate 'r' and 'arg' (assuming these are polar coordinates)
df['r'] = np.sqrt(df['x']**2 + df['y']**2)
df['arg'] = np.arctan2(df['y'], df['x'])
df.describe()
The description of dataframe after adding additional data is shown below.
Removing duplicate datapoints and shuffling the data.
# Remove duplicate rows based on 'arg' and 'r' to avoid overlapping data points
df_unique = df.drop_duplicates(subset=['arg', 'r'])
# Shuffle the dataset to ensure randomness
df_shuffled = df_unique.sample(frac=1, random_state=42).reset_index(drop=True)
df_shuffled.shape
After removing the duplicates the number of datapoints decrease from 216000 to 178637.
Splitting the dataset for testing and training followed by scaling down
# Prepare the data for training and testing
X = df_shuffled[['x', 'y', 'cos_theta1', 'sin_theta1', 'cos_theta2', 'sin_theta2',
'cos_theta3', 'sin_theta3', 'cos_theta1_plus_theta2',
'sin_theta1_plus_theta2']].values
y = df_shuffled[['θ1', 'θ2', 'θ3']].values
5
# Split the data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,
random_state=42)
# Normalize the input features (X)
scaler_X = StandardScaler()
X_train = scaler_X.fit_transform(X_train)
X_test = scaler_X.transform(X_test)
# Normalize the output labels (y)
scaler_y = StandardScaler()
y_train = scaler_y.fit_transform(y_train)
y_test = scaler_y.transform(y_test)
20% of the data generated is saved as test data and the rest 80% will be utilized for training the neural network.
Defining the neural network model
# Define the neural network model with Dropout for regularization
model = Sequential([
Dense(128, activation='relu', input_shape=(X_train.shape[1],)), # Input layer
with appropriate number of features
Dropout(0.2), # Dropout layer to prevent overfitting
Dense(256, activation='relu'), # Hidden layer
Dropout(0.2), # Dropout layer
Dense(256, activation='relu'), # Hidden layer
Dropout(0.2), # Dropout layer
Dense(128, activation='relu'), # Hidden layer
Dense(3) # Output layer with 3 neurons for θ1, θ2, θ3
])
A tabulated summary of this model is shown below:
Training the model
# Compile the model with Mean Squared Error loss and Adam optimizer
6
model.compile(optimizer='adam', loss='mean_squared_error', metrics=['mae'])
# Display the model's architecture
model.summary()
# Train the model
history = model.fit(X_train, y_train, epochs=200, batch_size=32,
validation_split=0.2)
# Evaluate the model on the test set
test_loss, test_mae = model.evaluate(X_test, y_test)
print(f'Test Loss: {test_loss}, Test MAE: {test_mae}')
The training runs for 200 epochs, and we see that both the training error and test error decrease steadily. Each
epoch took approximately 25 seconds to run, resulting in a total training time of about 1 hr 20 minutes.
The summary of first five and last five epochs are shown below:
Generating five random predictions and true values for comparison and judgement of accuracy
# Make predictions on the test set
predictions_scaled = model.predict(X_test)
# Inverse transform the scaled predictions to original scale
predictions = scaler_y.inverse_transform(predictions_scaled)
# Inverse transform the test labels to original scale for comparison
y_test_original = scaler_y.inverse_transform(y_test)
# Compare predictions to actual values for the first 5 test samples
for i in range(5):
print(f"Predicted: {predictions[i]}, Actual: {y_test_original[i]}")
7
The five samples outputed by the code is tabulated for easier comparison. The table is shown below.
Predicted angles (degrees) Actual angles (degrees)
Sl No.
𝜃1 𝜃2 𝜃3 𝜃1 𝜃2 𝜃3
1 128.30473 6.149439 327.9959 126.00 6.00 336.00
2 341.54443 51.88143 290.76877 336.00 60.00 294.00
3 63.66504 237.32436 1.6386272 66.00 240.00 0.00
4 55.617706 156.05963 108.68878 54.00 156.00 102.00
5 65.36024 214.5312 263.52808 66.00 210.00 264.00
Conclusion
As evident from the table above the model is not as good as expected, since the predictions made are not
absolutely accurate. But this can be improved by adding more training samples, increasing the number of
neurons in the neural network model or by increasing the number of training epochs.
But due to the memory and time constraints, none of the remedies are feasible on the available computational
device. But with a more sophisticated device, which is faster and more memory efficient, the model can be
improved a lot achieving near perfection.
Submitted by
Priyadarsan P John
ME2B149