Skip to content

Commit 3504833

Browse files
committed
fix bug of NLinkArm.py and modify random exapmle scripts
1 parent c49f982 commit 3504833

File tree

3 files changed

+121
-33
lines changed

3 files changed

+121
-33
lines changed

ArmNavigation/n_joint_arm_3d/NLinkArm.py

Lines changed: 89 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,21 @@ def transformation_matrix(self):
1313
a = self.dh_params_[2]
1414
d = self.dh_params_[3]
1515

16+
'''
1617
trans = np.array(
1718
[[math.cos(theta), -math.sin(theta), 0, a],
1819
[math.cos(alpha) * math.sin(theta), math.cos(alpha) * math.cos(theta), -math.sin(alpha), -d * math.sin(alpha)],
1920
[math.sin(alpha) * math.sin(theta), math.sin(alpha) * math.cos(theta), math.cos(alpha), d * math.cos(alpha)],
2021
[0, 0, 0, 1]])
22+
'''
23+
st = math.sin(theta)
24+
ct = math.cos(theta)
25+
sa = math.sin(alpha)
26+
ca = math.cos(alpha)
27+
trans = np.array([[ct, -st * ca, st * sa, a * ct],
28+
[st, ct * ca, -ct * sa, a * st],
29+
[0, sa, ca, d],
30+
[0, 0, 0, 1]])
2131

2232
return trans
2333

@@ -35,44 +45,66 @@ def __init__(self, dh_params_list):
3545
for i in range(len(dh_params_list)):
3646
self.link_list.append(Link(dh_params_list[i]))
3747

38-
self.fig = plt.figure()
39-
self.ax = Axes3D(self.fig)
40-
4148
def transformation_matrix(self):
4249
trans = np.identity(4)
4350
for i in range(len(self.link_list)):
4451
trans = np.dot(trans, self.link_list[i].transformation_matrix())
4552
return trans
4653

47-
def forward_kinematics(self):
54+
def forward_kinematics(self, plot=False):
4855
trans = self.transformation_matrix()
4956

5057
x = trans[0, 3]
5158
y = trans[1, 3]
5259
z = trans[2, 3]
53-
alpha = math.atan2(trans[1, 2], trans[1, 3])
54-
beta = math.atan2(trans[0, 2] * math.cos(alpha) + trans[1, 2] * math.sin(alpha), trans[2, 2])
55-
gamma = math.atan2(-trans[0, 0] * math.sin(alpha) + trans[1, 0] * math.cos(alpha), -trans[0, 1] * math.sin(alpha) + trans[1, 1] * math.cos(alpha))
60+
alpha, beta, gamma = self.calc_euler_angle()
61+
62+
if plot:
63+
self.fig = plt.figure()
64+
self.ax = Axes3D(self.fig)
65+
66+
x_list = []
67+
y_list = []
68+
z_list = []
69+
70+
trans = np.identity(4)
71+
72+
x_list.append(trans[0, 3])
73+
y_list.append(trans[1, 3])
74+
z_list.append(trans[2, 3])
75+
for i in range(len(self.link_list)):
76+
trans = np.dot(trans, self.link_list[i].transformation_matrix())
77+
x_list.append(trans[0, 3])
78+
y_list.append(trans[1, 3])
79+
z_list.append(trans[2, 3])
80+
81+
self.ax.plot(x_list, y_list, z_list, "o-", color="#00aa00", ms=4, mew=0.5)
82+
self.ax.plot([0], [0], [0], "o")
83+
84+
self.ax.set_xlim(-1, 1)
85+
self.ax.set_ylim(-1, 1)
86+
self.ax.set_zlim(-1, 1)
87+
88+
plt.show()
5689

5790
return [x, y, z, alpha, beta, gamma]
5891

59-
def basic_jacobian(self, ref_ee_pose):
92+
def basic_jacobian(self, ee_pose):
6093
basic_jacobian_mat = []
6194

6295
trans = np.identity(4)
6396
for i in range(len(self.link_list)):
97+
basic_jacobian_mat.append(self.link_list[i].basic_jacobian(trans, ee_pose[0:3]))
6498
trans = np.dot(trans, self.link_list[i].transformation_matrix())
65-
basic_jacobian_mat.append(self.link_list[i].basic_jacobian(trans, ref_ee_pose[0:3]))
6699

67-
#print(np.array(basic_jacobian_mat).T)
68100
return np.array(basic_jacobian_mat).T
69101

70-
def inverse_kinematics(self, ref_ee_pose):
71-
ee_pose = self.forward_kinematics()
72-
diff_pose = ee_pose - np.array(ref_ee_pose)
102+
def inverse_kinematics(self, ref_ee_pose, plot=False):
103+
for cnt in range(500):
104+
ee_pose = self.forward_kinematics()
105+
diff_pose = np.array(ref_ee_pose) - ee_pose
73106

74-
for cnt in range(1000):
75-
basic_jacobian_mat = self.basic_jacobian(ref_ee_pose)
107+
basic_jacobian_mat = self.basic_jacobian(ee_pose)
76108
alpha, beta, gamma = self.calc_euler_angle()
77109

78110
K_zyz = np.array([[0, -math.sin(alpha), math.cos(alpha) * math.sin(beta)],
@@ -82,12 +114,45 @@ def inverse_kinematics(self, ref_ee_pose):
82114
K_alpha[3:, 3:] = K_zyz
83115

84116
theta_dot = np.dot(np.dot(np.linalg.pinv(basic_jacobian_mat), K_alpha), np.array(diff_pose))
85-
self.update_joint_angles(theta_dot)
86-
117+
self.update_joint_angles(theta_dot / 100.)
118+
119+
if plot:
120+
self.fig = plt.figure()
121+
self.ax = Axes3D(self.fig)
122+
123+
x_list = []
124+
y_list = []
125+
z_list = []
126+
127+
trans = np.identity(4)
128+
129+
x_list.append(trans[0, 3])
130+
y_list.append(trans[1, 3])
131+
z_list.append(trans[2, 3])
132+
for i in range(len(self.link_list)):
133+
trans = np.dot(trans, self.link_list[i].transformation_matrix())
134+
x_list.append(trans[0, 3])
135+
y_list.append(trans[1, 3])
136+
z_list.append(trans[2, 3])
137+
138+
self.ax.plot(x_list, y_list, z_list, "o-", color="#00aa00", ms=4, mew=0.5)
139+
self.ax.plot([0], [0], [0], "o")
140+
141+
self.ax.set_xlim(-1, 1)
142+
self.ax.set_ylim(-1, 1)
143+
self.ax.set_zlim(-1, 1)
144+
145+
self.ax.plot([ref_ee_pose[0]], [ref_ee_pose[1]], [ref_ee_pose[2]], "o")
146+
plt.show()
147+
87148
def calc_euler_angle(self):
88149
trans = self.transformation_matrix()
89150

90151
alpha = math.atan2(trans[1][2], trans[0][2])
152+
if -math.pi / 2 <= alpha and alpha <= math.pi / 2:
153+
alpha = math.atan2(trans[1][2], trans[0][2]) + math.pi
154+
if -math.pi / 2 <= alpha and alpha <= math.pi / 2:
155+
alpha = math.atan2(trans[1][2], trans[0][2]) - math.pi
91156
beta = math.atan2(trans[0][2] * math.cos(alpha) + trans[1][2] * math.sin(alpha), trans[2][2])
92157
gamma = math.atan2(-trans[0][0] * math.sin(alpha) + trans[1][0] * math.cos(alpha), -trans[0][1] * math.sin(alpha) + trans[1][1] * math.cos(alpha))
93158

@@ -102,6 +167,9 @@ def update_joint_angles(self, diff_joint_angle_list):
102167
self.link_list[i].dh_params_[0] += diff_joint_angle_list[i]
103168

104169
def plot(self):
170+
self.fig = plt.figure()
171+
self.ax = Axes3D(self.fig)
172+
105173
x_list = []
106174
y_list = []
107175
z_list = []
@@ -119,6 +187,10 @@ def plot(self):
119187

120188
self.ax.plot(x_list, y_list, z_list, "o-", color="#00aa00", ms=4, mew=0.5)
121189
self.ax.plot([0], [0], [0], "o")
190+
191+
self.ax.set_xlabel("x")
192+
self.ax.set_ylabel("y")
193+
self.ax.set_zlabel("z")
122194

123195
self.ax.set_xlim(-1, 1)
124196
self.ax.set_ylim(-1, 1)
Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
11
import math
22
from NLinkArm import NLinkArm
33
import random
4-
import time
54

65
def random_val(min_val, max_val):
76
return min_val + random.random() * (max_val - min_val)
87

9-
for i in range(10):
8+
9+
if __name__ == "__main__":
10+
print("Start solving Forward Kinematics 10 times")
11+
12+
# init NLinkArm with Denavit-Hartenberg parameters of PR2
1013
n_link_arm = NLinkArm([[0., -math.pi/2, .1, 0.],
1114
[math.pi/2, math.pi/2, 0., 0.],
1215
[0., -math.pi/2, 0., .4],
1316
[0., math.pi/2, 0., 0.],
1417
[0., -math.pi/2, 0., .321],
1518
[0., math.pi/2, 0., 0.],
1619
[0., 0., 0., 0.]])
17-
18-
n_link_arm.set_joint_angles([random_val(-1, 1) for j in range(len(n_link_arm.link_list))])
19-
n_link_arm.plot()
20+
21+
for i in range(10):
22+
n_link_arm.set_joint_angles([random_val(-1, 1) for j in range(len(n_link_arm.link_list))])
23+
24+
ee_pose = n_link_arm.forward_kinematics(plot=True)
25+
print(ee_pose)
2026

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,27 @@
11
import math
22
from NLinkArm import NLinkArm
33
import random
4-
import time
54

65

7-
n_link_arm = NLinkArm([[0., -math.pi/2, .1, 0.],
8-
[math.pi/2, math.pi/2, 0., 0.],
9-
[0., -math.pi/2, 0., .4],
10-
[0., math.pi/2, 0., 0.],
11-
[0., -math.pi/2, 0., .321],
12-
[0., math.pi/2, 0., 0.],
13-
[0., 0., 0., 0.]])
6+
def random_val(min_val, max_val):
7+
return min_val + random.random() * (max_val - min_val)
148

15-
#n_link_arm.inverse_kinematics([-0.621, 0., 0., 0., 0., math.pi / 2])
16-
n_link_arm.inverse_kinematics([-0.5, 0., 0.1, 0., 0., math.pi / 2])
17-
n_link_arm.plot()
9+
if __name__ == "__main__":
10+
print("Start solving Inverse Kinematics 10 times")
11+
12+
# init NLinkArm with Denavit-Hartenberg parameters of PR2
13+
n_link_arm = NLinkArm([[0., -math.pi/2, .1, 0.],
14+
[math.pi/2, math.pi/2, 0., 0.],
15+
[0., -math.pi/2, 0., .4],
16+
[0., math.pi/2, 0., 0.],
17+
[0., -math.pi/2, 0., .321],
18+
[0., math.pi/2, 0., 0.],
19+
[0., 0., 0., 0.]])
20+
21+
for i in range(10):
22+
n_link_arm.inverse_kinematics([random_val(-0.5, 0.5),
23+
random_val(-0.5, 0.5),
24+
random_val(-0.5, 0.5),
25+
random_val(-0.5, 0.5),
26+
random_val(-0.5, 0.5),
27+
random_val(-0.5, 0.5)], plot=True)

0 commit comments

Comments
 (0)