Skip to content

Commit c1a7657

Browse files
committed
add two_joint_arm_to_point_control control
1 parent 36f948a commit c1a7657

File tree

4 files changed

+130
-83
lines changed

4 files changed

+130
-83
lines changed
2.11 MB
Loading
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
"""
2+
Inverse kinematics of a two-joint arm
3+
Left-click the plot to set the goal position of the end effector
4+
5+
Author: Daniel Ingram (daniel-s-ingram)
6+
Atsushi Sakai (@Atsushi_twi)
7+
"""
8+
9+
import matplotlib.pyplot as plt
10+
import numpy as np
11+
12+
13+
# Similation parameters
14+
Kp = 15
15+
dt = 0.01
16+
17+
# Link lengths
18+
l1 = l2 = 1
19+
20+
# Set initial goal position to the initial end-effector position
21+
x = 2
22+
y = 0
23+
24+
show_animation = True
25+
26+
if show_animation:
27+
plt.ion()
28+
29+
30+
def two_joint_arm(GOAL_TH=0.0, theta1=0.0, theta2=0.0):
31+
"""
32+
Computes the inverse kinematics for a planar 2DOF arm
33+
"""
34+
while True:
35+
try:
36+
theta2_goal = np.arccos(
37+
(x**2 + y**2 - l1**2 - l2**2) / (2 * l1 * l2))
38+
theta1_goal = np.math.atan2(y, x) - np.math.atan2(l2 *
39+
np.sin(theta2_goal), (l1 + l2 * np.cos(theta2_goal)))
40+
41+
if theta1_goal < 0:
42+
theta2_goal = -theta2_goal
43+
theta1_goal = np.math.atan2(
44+
y, x) - np.math.atan2(l2 * np.sin(theta2_goal), (l1 + l2 * np.cos(theta2_goal)))
45+
46+
theta1 = theta1 + Kp * ang_diff(theta1_goal, theta1) * dt
47+
theta2 = theta2 + Kp * ang_diff(theta2_goal, theta2) * dt
48+
except ValueError as e:
49+
print("Unreachable goal")
50+
51+
if show_animation:
52+
wrist = plot_arm(theta1, theta2, x, y)
53+
54+
# check goal
55+
d2goal = np.math.sqrt((wrist[0] - x)**2 + (wrist[1] - y)**2)
56+
57+
if abs(d2goal) < GOAL_TH and x is not None:
58+
return theta1, theta2
59+
60+
61+
def plot_arm(theta1, theta2, x, y):
62+
shoulder = np.array([0, 0])
63+
elbow = shoulder + np.array([l1 * np.cos(theta1), l1 * np.sin(theta1)])
64+
wrist = elbow + \
65+
np.array([l2 * np.cos(theta1 + theta2), l2 * np.sin(theta1 + theta2)])
66+
67+
plt.cla()
68+
69+
plt.plot([shoulder[0], elbow[0]], [shoulder[1], elbow[1]], 'k-')
70+
plt.plot([elbow[0], wrist[0]], [elbow[1], wrist[1]], 'k-')
71+
72+
plt.plot(shoulder[0], shoulder[1], 'ro')
73+
plt.plot(elbow[0], elbow[1], 'ro')
74+
plt.plot(wrist[0], wrist[1], 'ro')
75+
76+
plt.plot([wrist[0], x], [wrist[1], y], 'g--')
77+
plt.plot(x, y, 'g*')
78+
79+
plt.xlim(-2, 2)
80+
plt.ylim(-2, 2)
81+
82+
plt.show()
83+
plt.pause(dt)
84+
85+
return wrist
86+
87+
88+
def ang_diff(theta1, theta2):
89+
# Returns the difference between two angles in the range -pi to +pi
90+
return (theta1 - theta2 + np.pi) % (2 * np.pi) - np.pi
91+
92+
93+
def click(event):
94+
global x, y
95+
x = event.xdata
96+
y = event.ydata
97+
98+
99+
def animation():
100+
from random import random
101+
global x, y
102+
theta1 = theta2 = 0.0
103+
for i in range(5):
104+
x = 2.0 * random() - 1.0
105+
y = 2.0 * random() - 1.0
106+
theta1, theta2 = two_joint_arm(
107+
GOAL_TH=0.01, theta1=theta1, theta2=theta2)
108+
109+
110+
def main():
111+
fig = plt.figure()
112+
fig.canvas.mpl_connect("button_press_event", click)
113+
two_joint_arm()
114+
115+
116+
if __name__ == "__main__":
117+
# animation()
118+
main()

RoboticArm/two_joint_arm.py

Lines changed: 0 additions & 83 deletions
This file was deleted.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from unittest import TestCase
2+
3+
from ArmNavigation.two_joint_arm_to_point_control import two_joint_arm_to_point_control as m
4+
5+
print(__file__)
6+
7+
8+
class Test(TestCase):
9+
10+
def test1(self):
11+
m.show_animation = False
12+
m.animation()

0 commit comments

Comments
 (0)