Day 4: (Thu Sep 5) Kinematics Etc.¶
Notes for 2019-09-05. See also the Fall 2019 Calendar.
Notes from Day 3¶
Agenda¶
Administrative
If needed, please fix your post to use the code syntax highlighting as per code formatting in posts
Assignments
In-class
Demos for Exercise: Dynamic Gesture on a Simulated Double Pendulum
Brief numpy tutorial.
Discussion of two-link kinematics.
A few videos.
Discussion of common platform ideas.
Videos¶
SCARA robot demo :https://www.youtube.com/watch?v=k_nHFSdk8Sg
SCARA robots demo: https://www.youtube.com/watch?v=4RQiGz-ygsQ
Lecture code samples¶
NumPy¶
We may use some of the NumPy library for numerical computing, which isn’t part of core Python.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | # Make the numpy library available under the name 'np'.
import numpy as np
# Create a 3-element zero vector (all floating point)
z = np.zeros((3))
print(z)
# Create a 3-element zero vector (integer)
z = np.zeros((3), dtype=np.int)
print(z)
# Create a 3x4 zero matrix (3 rows, 4 columns).
z = np.zeros((3,4))
print(z)
# Create an uninitialized 2x3 matrix (2 rows, 3 columns).
u = np.ndarray((2,3))
print(u)
# Create a 3x3 identity matrix.
I = np.array(((1.0,0,0),(0,1.0,0),(0,0,1.0)))
print(I)
# Create a 3x3 identity matrix.
I = np.eye(3)
print(I)
# Create a random 3-element vector.
R = np.random.rand(3)
print(R)
# Multiply by a scalar.
print(10 * R)
# Vector arithmetic. The following operate element-by-element.
print(10 * R**2 + R)
print(np.sin(R))
# The same notation provides efficient access to large arrays.
big = np.random.rand(10000)
# Calculate the magnitude of the high-dimensional vector:
magnitude = np.sqrt(np.dot(big,big))
print("Long vector magnitude:", magnitude)
# The same is available as a primitive:
print("Long vector magnitude:", np.linalg.norm(big))
# For more, see https://docs.scipy.org/doc/numpy/reference/routines.linalg.html
|
Reference manual items:
And the broader SciPy:
Not to mention more specialized libraries:
Two-Link Forward Kinematics¶
1 2 3 4 5 6 7 8 9 10 11 | def forwardKinematics(self, q):
"""Compute the forward kinematics. Returns the world-coordinate Cartesian position of the elbow
and endpoint for a given joint angle vector.
:param q: two-element list or ndarray with [q1, q2] joint angles
:return: tuple (elbow, end) of two-element ndarrays with [x,y] locations
"""
elbow = self.origin + np.array((self.l1 * math.sin(q[0]), -self.l1 * math.cos(q[0])))
end = elbow + np.array((self.l2 * math.sin(q[0]+q[1]), -self.l2 * math.cos(q[0]+q[1])))
return elbow, end
|
Two-Link Inverse Kinematics¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | def endpointIK(self, target):
"""Compute two inverse kinematics solutions for a target end position. The
target is a Cartesian position vector (two-element ndarray) in world coordinates,
and the result vectors are joint angles as ndarrays [q0, q1].
If the target is out of reach, returns the closest pose.
"""
# translate the target vector into body coordinates
target = target - self.origin
# find the position of the point in polar coordinates
radiussq = np.dot(target, target)
radius = math.sqrt(radiussq)
# theta is the angle of target point w.r.t. -Y axis, same origin as arm
theta = math.atan2(target[0], -target[1])
# use the law of cosines to compute the elbow angle
# R**2 = l1**2 + l2**2 - 2*l1*l2*cos(pi - elbow)
# both elbow and -elbow are valid solutions
acosarg = (radiussq - self.l1**2 - self.l2**2) / (-2 * self.l1 * self.l2)
if acosarg < -1.0: elbow_supplement = math.pi
elif acosarg > 1.0: elbow_supplement = 0.0
else: elbow_supplement = math.acos(acosarg)
# use the law of sines to find the angle at the bottom vertex of the triangle defined by the links
# radius / sin(elbow_supplement) = l2 / sin(alpha)
if radius > 0.0:
alpha = math.asin(self.l2 * math.sin(elbow_supplement) / radius)
else:
alpha = 0.0
# compute the two solutions with opposite elbow sign
soln1 = np.array((theta - alpha, math.pi - elbow_supplement))
soln2 = np.array((theta + alpha, elbow_supplement - math.pi))
return soln1, soln2
|