Skip to main content
Glama

nUR MCP Server

by nonead
manipulation.py38.9 kB
import math from numpy import * ### HELPER FUNCTIONS ### def randomVec(x): ''' Generates a vector of length x, each component being a random float b/w -10 and 10 ''' return random.uniform(-10,10,(x,1)) def randomUnitAxisAngle(): ''' Generates a random unit axis and an angle ''' # Random longitude u = random.uniform(0, 1) longitude = 2*math.pi*u # Random latitude v = random.uniform(0, 1) latitude = 2*math.pi*v # Random unit rotation axis axis = zeros((3,1)) axis[0] = math.cos(latitude)*math.cos(longitude) axis[1] = math.cos(latitude)*math.sin(longitude) axis[2] = math.sin(latitude) # Random angle b/w 0 and 2pi theta = 2*math.pi*random.uniform(0, 1) return axis, theta def normalize(v): ''' Returns the normalized version of the vector v ''' norm = linalg.norm(v) if norm == 0: return v return v/norm def is_identity_matrix(M): ''' Returns True if input M is close to an identity matrix ''' if len(M) != len(M[0]): return False c = list() for i, row in enumerate(M): for j, val in enumerate(row): if i==j: if val < 1.001 and val > 0.999: c.append(True) else: c.append(False) else: if abs(val) < 0.001: c.append(True) else: c.append(False) return all(c) def is_rot_matrix(R): ''' Returns True if input R is a valid rotation matrix. ''' R = asarray(R) return is_identity_matrix(dot(R.T,R)) and (abs(linalg.det(R)-1) < 0.001) ### MAIN FUNCTIONS ### def RotInv(R): ''' Takes a rotation matrix belonging to SO(3) and returns its inverse. Example: R = [[.707,-.707,0],[.707,.707,0],[0,0,1]] RotInv(R) >> array([[ 0.707, 0.707, 0. ], [-0.707, 0.707, 0. ], [ 0. , 0. , 1. ]]) ''' R = asarray(R) assert is_rot_matrix(R), 'Not a valid rotation matrix' return R.T def VecToso3(w): ''' Takes a 3-vector representing angular velocity and returns the 3x3 skew-symmetric matrix version, an element of so(3). Example: w = [2, 1, -4] VecToso3(w) >> array([[ 0, 4, 1], [-4, 0, -2], [-1, 2, 0]]) ''' w = asarray(w) assert len(w) == 3, 'Not a 3-vector' w = w.flatten() w_so3mat = array([[0, -w[2], w[1]], [w[2], 0, -w[0]], [-w[1], w[0], 0]]) return w_so3mat def so3ToVec(w_so3mat): ''' Takes a 3x3 skew-symmetric matrix (an element of so(3)) and returns the corresponding 3-vector. Example: w_so3mat = [[ 0, 4, 1],[-4, 0, -2],[-1, 2, 0]] so3ToVec(w_so3mat) >> array([[ 2], [ 1], [-4]]) ''' w_so3mat = asarray(w_so3mat) assert w_so3mat.shape == (3,3), 'Not a 3x3 matrix' w = array([[w_so3mat[2,1]], [w_so3mat[0,2]], [w_so3mat[1,0]]]) return w def AxisAng3(r): ''' Takes a 3-vector of exp coords r = w_unit*theta and returns w_unit and theta. Example: r = [2, 1, -4] w_unit, theta = AxisAng3(r) w_unit >> array([ 0.43643578, 0.21821789, -0.87287156]) theta >> 4.5825756949558398 ''' r = asarray(r) assert len(r) == 3, 'Not a 3-vector' theta = linalg.norm(r) w_unit = normalize(r) return w_unit, theta def MatrixExp3(r): ''' Takes a 3-vector of exp coords r = w_unit*theta and returns the corresponding rotation matrix R (an element of SO(3)). Example: r = [2, 1, -4] MatrixExp3(r) >> array([[ 0.08568414, -0.75796072, -0.64664811], [ 0.97309386, -0.07566572, 0.2176305 ], [-0.21388446, -0.64789679, 0.73108357]]) ''' r = asarray(r) assert len(r) == 3, 'Not a 3-vector' w_unit, theta = AxisAng3(r) w_so3mat = VecToso3(w_unit) R = identity(3) + math.sin(theta)*w_so3mat + (1-math.cos(theta))*dot(w_so3mat, w_so3mat) assert is_rot_matrix(R), 'Did not produce a valid rotation matrix' return R def MatrixLog3(R): ''' Takes a rotation matrix R and returns the corresponding 3-vector of exp coords r = w_unit*theta. Example: R = [[.707,-.707,0],[.707,.707,0],[0,0,1]] MatrixLog3(R) >> array([[ 0. ], [ 0. ], [ 0.78554916]]) ''' R = asarray(R) assert is_rot_matrix(R), 'Not a valid rotation matrix' if is_identity_matrix(R): return zeros((3,1)) if trace(R) > -1.001 and trace(R) < -0.999: theta = math.pi c = max(diag(R)) if c == R[2,2]: w_unit = array([[R[0,2]],[R[1,2]],[1+c]])*1/((2*(1+c))**0.5) return w_unit*theta elif c == R[1,1]: w_unit = array([[R[0,1]],[1+c],[R[2,1]]])*1/((2*(1+c))**0.5) return w_unit*theta elif c == R[0,0]: w_unit = array([[1+c],[R[1,0]],[R[2,0]]])*1/((2*(1+c))**0.5) return w_unit*theta theta = math.acos((trace(R)-1)/2) w_so3mat = (R - R.T)/(2*math.sin(theta)) w_unit = normalize(so3ToVec(w_so3mat)) return w_unit*theta def RpToTrans(R,p): ''' Takes a rotation matrix R and a point (3-vector) p, and returns the corresponding 4x4 transformation matrix T, an element of SE(3). Example: R = [[.707,-.707,0],[.707,.707,0],[0,0,1]] p = [5,-4,9] RpToTrans(R,p) >> array([[ 0.707, -0.707, 0. , 5. ], [ 0.707, 0.707, 0. , -4. ], [ 0. , 0. , 1. , 9. ], [ 0. , 0. , 0. , 1. ]]) ''' p = asarray(p) R = asarray(R) assert len(p) == 3, "Point not a 3-vector" assert is_rot_matrix(R), "R not a valid rotation matrix" p.shape = (3,1) T = vstack((hstack((R,p)), array([0,0,0,1]))) return T def TransToRp(T): ''' Takes a transformation matrix T and returns the corresponding R and p. Example: T = [[0.707,-0.707,0,5],[0.707,0.707,0,-4],[0,0,1,9],[0,0,0,1]] R, p = TransToRp(T) R >> array([[ 0.707, -0.707, 0. ], [ 0.707, 0.707, 0. ], [ 0. , 0. , 1. ]]) p >> array([[ 5.], [-4.], [ 9.]]) ''' T = asarray(T) assert T.shape == (4,4), "Input not a 4x4 matrix" R = T[:3,:3] assert is_rot_matrix(R), "Input not a valid transformation matrix" assert allclose([0,0,0,1],T[-1],atol=1e-03), "Last row of homogenous T matrix should be [0,0,0,1]" p = T[:3,-1] p.shape = (3,1) return R, p def TransInv(T): ''' Returns inverse of transformation matrix T. Example: T = [[0.707,-0.707,0,5],[0.707,0.707,0,-4],[0,0,1,9],[0,0,0,1]] TransInv(T) >> array([[ 0.707, 0.707, 0. , -0.707], [-0.707, 0.707, 0. , 6.363], [ 0. , 0. , 1. , -9. ], [ 0. , 0. , 0. , 1. ]]) ''' T = asarray(T) R, p = TransToRp(T) T_inv = RpToTrans(RotInv(R), dot(-RotInv(R),p)) return T_inv def VecTose3(V): ''' Takes a 6-vector (representing spatial velocity) and returns the corresponding 4x4 matrix, an element of se(3). Example: V = [3,2,5,-3,7,0] VecTose3(V) >> array([[ 0., -5., 2., -3.], [ 5., 0., -3., 7.], [-2., 3., 0., 0.], [ 0., 0., 0., 0.]]) ''' V = asarray(V) assert len(V) == 6, "Input not a 6-vector" V.shape = (6,1) w = V[:3] w_so3mat = VecToso3(w) v = V[3:] V_se3mat = vstack((hstack((w_so3mat,v)), zeros(4))) return V_se3mat def se3ToVec(V_se3mat): ''' Takes an element of se(3) and returns the corresponding (6-vector) spatial velocity. Example: V_se3mat = [[ 0., -5., 2., -3.], [ 5., 0., -3., 7.], [-2., 3., 0., 0.], [ 0., 0., 0., 0.]] se3ToVec(V_se3mat) >> array([[ 3.], [ 2.], [ 5.], [-3.], [ 7.], [ 0.]]) ''' V_se3mat = asarray(V_se3mat) assert V_se3mat.shape == (4,4), "Matrix is not 4x4" w_so3mat = V_se3mat[:3,:3] w = so3ToVec(w_so3mat) v = V_se3mat[:3,-1] v.shape = (3,1) V = vstack((w,v)) return V def Adjoint(T): ''' Takes a transformation matrix T and returns the 6x6 adjoint representation [Ad_T] Example: T = [[0.707,-0.707,0,5],[0.707,0.707,0,-4],[0,0,1,9],[0,0,0,1]] Adjoint(T) >> array([[ 0.707, -0.707, 0. , 0. , 0. , 0. ], [ 0.707, 0.707, 0. , 0. , 0. , 0. ], [ 0. , 0. , 1. , 0. , 0. , 0. ], [-6.363, -6.363, -4. , 0.707, -0.707, 0. ], [ 6.363, -6.363, -5. , 0.707, 0.707, 0. ], [ 6.363, 0.707, 0. , 0. , 0. , 1. ]]) ''' T = asarray(T) assert T.shape == (4,4), "Input not a 4x4 matrix" R, p = TransToRp(T) p = p.flatten() p_skew = array([[0, -p[2], p[1]], [p[2], 0, -p[0]], [-p[1], p[0], 0]]) ad1 = vstack((R, dot(p_skew,R))) ad2 = vstack((zeros((3,3)),R)) adT = hstack((ad1,ad2)) return adT def ScrewToAxis(q,s_hat,h): ''' Takes a point q (3-vector) on the screw, a unit axis s_hat (3-vector) in the direction of the screw, and a screw pitch h (scalar), and returns the corresponding 6-vector screw axis S (a normalized spatial velocity). Example: q = [3,0,0] s_hat = [0,0,1] h = 2 ScrewToAxis(q,s_hat,h) >> array([[ 0], [ 0], [ 1], [ 0], [-3], [ 2]]) ''' q = asarray(q) s_hat = asarray(s_hat) assert len(q) == len(s_hat) == 3, "q or s_hat not a 3-vector" assert abs(linalg.norm(s_hat) - 1) < 0.001, "s_hat not a valid unit vector" assert isscalar(h), "h not a scalar" q = q.flatten() s_hat = s_hat.flatten() v_wnorm = -cross(s_hat, q) + h*s_hat v_wnorm.shape = (3,1) w_unit = s_hat w_unit.shape = (3,1) S = vstack((w_unit,v_wnorm)) return S def AxisAng6(STheta): ''' Takes a 6-vector of exp coords STheta and returns the screw axis S and the distance traveled along/ about the screw axis theta. Example: STheta = [0,0,1,0,-3,2] S, theta = AxisAng6(STheta) S >> array([[ 0.], [ 0.], [ 1.], [ 0.], [-3.], [ 2.]]) theta >> 1.0 ''' STheta = asarray(STheta) assert len(STheta) == 6, 'Input not a 6-vector' w = STheta[:3] v = STheta[3:] if linalg.norm(w) == 0: theta = linalg.norm(v) v_unit = normalize(v) v_unit.shape = (3,1) S = vstack((zeros((3,1)), v_unit)) return S, theta theta = linalg.norm(w) w_unit = normalize(w) w_unit.shape = (3,1) v_unit = v/theta v_unit.shape = (3,1) S = vstack((w_unit,v_unit)) return S, theta def MatrixExp6(STheta): ''' Takes a 6-vector of exp coords STheta and returns the corresponding 4x4 transformation matrix T. Example: STheta = [0,0,1,0,-3,2] MatrixExp6(STheta) >> array([[ 0.54030231, -0.84147098, 0. , 1.37909308], [ 0.84147098, 0.54030231, 0. , -2.52441295], [ 0. , 0. , 1. , 2. ], [ 0. , 0. , 0. , 1. ]]) ''' STheta = asarray(STheta) assert len(STheta) == 6, 'Input not a 6-vector' S, theta = AxisAng6(STheta) w_unit = S[:3] v_unit = S[3:] vTheta = STheta[3:] vTheta.shape = (3,1) if linalg.norm(w_unit) == 0: R = identity(3) p = vTheta T = RpToTrans(R,p) return T r = w_unit*theta R = MatrixExp3(r) w_so3mat = VecToso3(w_unit) p = dot((identity(3)*theta+(1-math.cos(theta))*w_so3mat+(theta-math.sin(theta))*dot(w_so3mat,w_so3mat)), v_unit) T = RpToTrans(R,p) return T def MatrixLog6(T): ''' Takes a transformation matrix T and returns the corresponding 6-vector of exp coords STheta. Example: T = [[ 0.54030231, -0.84147098, 0. , 1.37909308], [ 0.84147098, 0.54030231, 0. , -2.52441295], [ 0. , 0. , 1. , 2. ], [ 0. , 0. , 0. , 1. ]] MatrixLog6(T): >> array([[ 0.00000000e+00], [ 0.00000000e+00], [ 9.99999995e-01], [ 1.12156694e-08], [ -2.99999999e+00], [ 2.00000000e+00]]) ''' T = asarray(T) assert T.shape == (4,4), "Input not a 4x4 matrix" R, p = TransToRp(T) if is_identity_matrix(R): w_unit = zeros((3,1)) vTheta = p STheta = vstack((w_unit, p)) return STheta if trace(R) > -1.001 and trace(R) < -0.999: theta = math.pi wTheta = MatrixLog3(R) w_unit = wTheta/theta w_so3mat = VecToso3(w_unit) Ginv = identity(3)/theta - w_so3mat/2 + (1/theta - 1/(math.tan(theta/2)*2))*dot(w_so3mat,w_so3mat) v_unit = dot(Ginv, p) vTheta = v_unit*theta STheta = vstack((wTheta, vTheta)) return STheta theta = math.acos((trace(R)-1)/2) w_so3mat = (R - R.T)/(2*math.sin(theta)) Ginv = identity(3)/theta - w_so3mat/2 + (1/theta - 1/(math.tan(theta/2)*2))*dot(w_so3mat,w_so3mat) wTheta = MatrixLog3(R) v_unit = dot(Ginv, p) vTheta = v_unit*theta STheta = vstack((wTheta, vTheta)) return STheta def FKinFixed(M,Slist,thetalist): ''' Takes - an element of SE(3): M representing the configuration of the end-effector frame when the manipulator is at its home position (all joint thetas = 0), - a list of screw axes Slist for the joints w.r.t fixed world frame, - a list of joint coords thetalist, and returns the T of end-effector frame w.r.t. fixed world frame when the joints are at the thetas specified. Example: S1 = [0,0,1,4,0,0] S2 = [0,0,0,0,1,0] S3 = [0,0,-1,-6,0,-0.1] Slist = [S1, S2, S3] thetalist = [math.pi/2, 3, math.pi] M = [[-1, 0, 0, 0], [ 0, 1, 0, 6], [ 0, 0, -1, 2], [ 0, 0, 0, 1]] FKinFixed(M,Slist,thetalist) >> array([[ -1.14423775e-17, 1.00000000e+00, 0.00000000e+00, -5.00000000e+00], [ 1.00000000e+00, 1.14423775e-17, 0.00000000e+00, 4.00000000e+00], [ 0.00000000e+00, 0.00000000e+00, -1.00000000e+00, 1.68584073e+00], [ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]]) ''' M = asarray(M) R_M = TransToRp(M)[0] assert M.shape == (4,4), "M not a 4x4 matrix" assert len(Slist[0]) == 6, "Incorrect Screw Axis length" Slist = asarray(Slist).T c = MatrixExp6(Slist[:,0]*thetalist[0]) for i in range(len(thetalist)-1): nex = MatrixExp6(Slist[:,i+1]*thetalist[i+1]) c = dot(c, nex) T_se = dot(c, M) return T_se def FKinBody(M,Blist,thetalist): ''' Same as FKinFixed, except here the screw axes are expressed in the end-effector frame. Example: B1 = [0,0,-1,2,0,0] B2 = [0,0,0,0,1,0] B3 = [0,0,1,0,0,0.1] Blist = [S1b, S2b, S3b] thetalist = [math.pi/2, 3, math.pi] M = [[-1, 0, 0, 0], [ 0, 1, 0, 6], [ 0, 0, -1, 2], [ 0, 0, 0, 1]] FKinBody(M,Blist,thetalist) >> array([[ -1.14423775e-17, 1.00000000e+00, 0.00000000e+00, -5.00000000e+00], [ 1.00000000e+00, 1.14423775e-17, 0.00000000e+00, 4.00000000e+00], [ 0.00000000e+00, 0.00000000e+00, -1.00000000e+00, 1.68584073e+00], [ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]]) ''' M = asarray(M) R_M = TransToRp(M)[0] assert M.shape == (4,4), "M not a 4x4 matrix" assert len(Blist[0]) == 6, "Incorrect Screw Axis length" Blist = asarray(Blist).T c = dot(M, MatrixExp6(Blist[:,0]*thetalist[0])) for i in range(len(thetalist)-1): nex = MatrixExp6(Blist[:,i+1]*thetalist[i+1]) c = dot(c, nex) T_se = c return T_se ### end of HW2 functions ############################# ### start of HW3 functions ########################### def FixedJacobian(Slist,thetalist): ''' Takes a list of joint angles (thetalist) and a list of screw axes (Slist) expressed in fixed space frame, and returns the space Jacobian (a 6xN matrix, where N is the # joints). Example: S1 = [0,0,1,4,0,0] S2 = [0,0,0,0,1,0] S3 = [0,0,-1,-6,0,-0.1] Slist = [S1, S2, S3] thetalist = [math.pi/2, 3, math.pi] FixedJacobian(Slist,thetalist) >> array([[ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], [ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], [ 1.00000000e+00, 0.00000000e+00, -1.00000000e+00], [ 4.00000000e+00, -1.00000000e+00, -4.00000000e+00], [ 0.00000000e+00, 1.11022302e-16, -5.00000000e+00], [ 0.00000000e+00, 0.00000000e+00, -1.00000000e-01]]) ''' N = len(thetalist) J = zeros((6,N)) Slist = asarray(Slist).T J[:,0] = Slist[:,0] for k in range(1,N): c = MatrixExp6(Slist[:,0]*thetalist[0]) for i in range(k-1): nex = MatrixExp6(Slist[:,i+1]*thetalist[i+1]) c = dot(c, nex) J[:,k] = dot(Adjoint(c), Slist[:,k]) return J def BodyJacobian(Blist,thetalist): ''' Takes a list of joint angles (thetalist) and a list of screw axes (Blist) expressed in end-effector body frame, and returns the body Jacobian (a 6xN matrix, where N is the # joints). Example: B1 = [0,0,-1,2,0,0] B2 = [0,0,0,0,1,0] B3 = [0,0,1,0,0,0.1] Blist = [B1, B2, B3] thetalist = [math.pi/2, 3, math.pi] BodyJacobian(Blist,thetalist) >> array([[ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], [ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], [ -1.00000000e+00, 0.00000000e+00, 1.00000000e+00], [ -5.00000000e+00, 1.22464680e-16, 0.00000000e+00], [ -6.12323400e-16, -1.00000000e+00, 0.00000000e+00], [ 0.00000000e+00, 0.00000000e+00, 1.00000000e-01]]) ''' N = len(thetalist) J = zeros((6,N)) Blist = asarray(Blist).T J[:,N-1] = Blist[:,N-1] for k in range(N-1): c = MatrixExp6(-Blist[:,k+1]*thetalist[k+1]) for i in range(k+2, len(thetalist)): nex = MatrixExp6(-Blist[:,i]*thetalist[i]) c = dot(nex, c) J[:,k] = dot(Adjoint(c), Blist[:,k]) return J def IKinBody(Blist, M, T_sd, thetalist_init, wthresh, vthresh): ''' A numerical inverse kinematics routine based on Newton-Raphson method. Takes a list of screw axes (Blist) expressed in end-effector body frame, the end-effector zero configuration (M), the desired end-effector configuration (T_sd), an initial guess of joint angles (thetalist_init), and small positive scalar thresholds (wthresh, vthresh) controlling how close the final solution thetas must be to the desired thetas. Example: wthresh = 0.01 vthresh = 0.001 M = [[1,0,0,-.817],[0,0,-1,-.191],[0,1,0,-.006],[0,0,0,1]] T_sd = [[0,1,0,-.6],[0,0,-1,.1],[-1,0,0,.1],[0,0,0,1]] thetalist_init = [0]*6 B1 = [0,1,0,.191,0,.817] B2 = [0,0,1,.095,-.817,0] B3 = [0,0,1,.095,-.392,0] B4 = [0,0,1,.095,0,0] B5 = [0,-1,0,-.082,0,0] B6 = [0,0,1,0,0,0] Blist = [B1,B2,B3,B4,B5,B6] round(IKinBody(Blist, M, T_sd, thetalist_init, wthresh, vthresh), 3) >> array([[ 0. , 0. , 0. , 0. , 0. , 0. ], [-0.356, -0.535, 0.468, 1.393, -0.356, -2.897], [-0.399, -1.005, 1.676, -0.434, -0.1 , -1.801], [-0.516, -1.062, 1.731, -1.63 , -0.502, -0.607], [-0.493, -0.923, 1.508, -0.73 , -0.289, -1.42 ], [-0.472, -0.818, 1.365, -0.455, -0.467, -1.662], [-0.469, -0.834, 1.395, -0.561, -0.467, -1.571]]) ''' T_sd = asarray(T_sd) assert T_sd.shape == (4,4), "T_sd not a 4x4 matrix" maxiterates = 100 N = len(thetalist_init) jointAngles = asarray(thetalist_init).reshape(1,N) T_sb = FKinBody(M, Blist, thetalist_init) Vb = MatrixLog6(dot(TransInv(T_sb), T_sd)) wb = Vb[:3, 0] vb = Vb[3:, 0] thetalist_i = asarray(thetalist_init) i = 0 while i<maxiterates and (linalg.norm(wb)>wthresh or linalg.norm(vb)>vthresh): thetalist_next = thetalist_i.reshape(N,1) + dot(linalg.pinv(BodyJacobian(Blist,thetalist_i)), Vb) # thetalist_next = (thetalist_next + pi)%(2*pi) - pi jointAngles = vstack((jointAngles, thetalist_next.reshape(1,N))) T_sb = FKinBody(M, Blist, thetalist_next.flatten()) Vb = MatrixLog6(dot(TransInv(T_sb), T_sd)) thetalist_i = thetalist_next.reshape(N,) wb = Vb[:3, 0] vb = Vb[3:, 0] i += 1 return jointAngles def IKinFixed(Slist, M, T_sd, thetalist_init, wthresh, vthresh): ''' Similar to IKinBody, except the screw axes are in the fixed space frame. Example: M = [[1,0,0,0],[0,1,0,0],[0,0,1,0.910],[0,0,0,1]] T_sd = [[1,0,0,.4],[0,1,0,0],[0,0,1,.4],[0,0,0,1]] thetalist_init = [0]*7 S1 = [0,0,1,0,0,0] S2 = [0,1,0,0,0,0] S3 = [0,0,1,0,0,0] S4 = [0,1,0,-0.55,0,0.045] S5 = [0,0,1,0,0,0] S6 = [0,1,0,-0.85,0,0] S7 = [0,0,1,0,0,0] Slist = [S1,S2,S3,S4,S5,S6,S7] round(IKinFixed(Slist, M, T_sd, thetas, wthresh, vthresh), 3) >> array([[ 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [ 0. , 4.471, -0. , -11.333, -0. , 6.863, -0. ], [ -0. , 3.153, -0. , -5.462, -0. , 2.309, 0. ], [ -0. , -1.006, 0. , 5.679, -0. , -4.673, 0. ], [ -0. , 1.757, 0. , -0.953, 0. , -0.804, -0. ], [ -0. , 1.754, 0. , -2.27 , -0. , 0.516, -0. ], [ 0. , 1.27 , 0. , -1.85 , -0. , 0.58 , -0. ], [ 0. , 1.367, 0. , -1.719, -0. , 0.351, -0. ], [ 0. , 1.354, 0. , -1.71 , -0. , 0.356, -0. ]]) ''' T_sd = asarray(T_sd) assert T_sd.shape == (4,4), "T_sd not a 4x4 matrix" maxiterates = 100 N = len(thetalist_init) jointAngles = asarray(thetalist_init).reshape(1,N) T_sb = FKinFixed(M, Slist, thetalist_init) Vb = MatrixLog6(dot(TransInv(T_sb), T_sd)) wb = Vb[:3, 0] vb = Vb[3:, 0] thetalist_i = asarray(thetalist_init) i = 0 while i<maxiterates and (linalg.norm(wb)>wthresh or linalg.norm(vb)>vthresh): Jb = dot(Adjoint(TransInv(T_sb)), FixedJacobian(Slist,thetalist_i)) thetalist_next = thetalist_i.reshape(N,1) + dot(linalg.pinv(Jb), Vb) jointAngles = vstack((jointAngles, thetalist_next.reshape(1,N))) T_sb = FKinFixed(M, Slist, thetalist_next.flatten()) Vb = MatrixLog6(dot(TransInv(T_sb), T_sd)) thetalist_i = thetalist_next.reshape(N,) wb = Vb[:3, 0] vb = Vb[3:, 0] i += 1 return jointAngles ### end of HW3 functions ############################# ### start of HW4 functions ########################### def CubicTimeScaling(T,t): ''' Takes a total travel time T and the current time t satisfying 0 <= t <= T and returns the path parameter s corresponding to a motion that begins and ends at zero velocity. Example: CubicTimeScaling(10, 7) >> 0.78399 ''' assert t >= 0 and t <= T, 'Invalid t' s = (3./(T**2))*(t**2) - (2./(T**3))*(t**3) return s def QuinticTimeScaling(T,t): ''' Takes a total travel time T and the current time t satisfying 0 <= t <= T and returns the path parameter s corresponding to a motion that begins and ends at zero velocity and zero acceleration. Example: QuinticTimeScaling(10,7) >> 0.83692 ''' assert t >= 0 and t <= T, 'Invalid t' s = (10./(T**3))*(t**3) + (-15./(T**4))*(t**4) + (6./(T**5))*(t**5) return s def JointTrajectory(thetas_start, thetas_end, T, N, method='cubic'): ''' Takes initial joint positions (n-dim) thetas_start, final joint positions thetas_end, the time of the motion T in seconds, the number of points N >= 2 in the discrete representation of the trajectory, and the time-scaling method (cubic or quintic) and returns a trajectory as a matrix with N rows, where each row is an n-vector of joint positions at an instant in time. The trajectory is a straight-line motion in joint space. Example: thetas_start = [0.1]*6 thetas_end = [pi/2]*6 T = 2 N = 5 JointTrajectory(thetas_start, thetas_end, T, N, 'cubic') >> array([[ 0.1 , 0.1 , 0.1 , 0.1 , 0.1 , 0.1 ], [ 0.33 , 0.33 , 0.33 , 0.33 , 0.33 , 0.33 ], [ 0.835, 0.835, 0.835, 0.835, 0.835, 0.835], [ 1.341, 1.341, 1.341, 1.341, 1.341, 1.341], [ 1.571, 1.571, 1.571, 1.571, 1.571, 1.571]]) ''' assert len(thetas_start) == len(thetas_end), 'Incompatible thetas' assert N >= 2, 'N must be >= 2' assert isinstance(N, int), 'N must be an integer' assert method == 'cubic' or method == 'quintic', 'Incorrect time-scaling method argument' trajectory = asarray(thetas_start) if method == 'cubic': for i in range(1,N): t = i*float(T)/(N-1) s = CubicTimeScaling(T,t) thetas_s = asarray(thetas_start)*(1-s) + asarray(thetas_end)*s trajectory = vstack((trajectory, thetas_s)) return trajectory elif method == 'quintic': for i in range(1,N): t = i*float(T)/(N-1) s = QuinticTimeScaling(T,t) thetas_s = asarray(thetas_start)*(1-s) + asarray(thetas_end)*s trajectory = vstack((trajectory, thetas_s)) return trajectory def ScrewTrajectory(X_start, X_end, T, N, method='cubic'): ''' Similar to JointTrajectory, except that it takes the initial end-effector configuration X_start in SE(3), the final configuration X_end, and returns the trajectory as a 4N x 4 matrix in which every 4 rows is an element of SE(3) separated in time by T/(N-1). This represents a discretized trajectory of the screw motion from X_start to X_end. Example: thetas_start = [0.1]*6 thetas_end = [pi/2]*6 M_ur5 = [[1,0,0,-.817],[0,0,-1,-.191],[0,1,0,-.006],[0,0,0,1]] S1_ur5 = [0,0,1,0,0,0] S2_ur5 = [0,-1,0,.089,0,0] S3_ur5 = [0,-1,0,.089,0,.425] S4_ur5 = [0,-1,0,.089,0,.817] S5_ur5 = [0,0,-1,.109,-.817,0] S6_ur5 = [0,-1,0,-.006,0,.817] Slist_ur5 = [S1_ur5,S2_ur5,S3_ur5,S4_ur5,S5_ur5,S6_ur5] X_start = FKinFixed(M_ur5, Slist_ur5, thetas_start) X_end = FKinFixed(M_ur5, Slist_ur5, thetas_end) T = 2 N = 3 ScrewTrajectory(X_start, X_end, T, N, 'quintic') >> array([[ 0.922, -0.388, 0.004, -0.764], [-0.007, -0.029, -1. , -0.268], [ 0.388, 0.921, -0.03 , -0.124], [ 0. , 0. , 0. , 1. ], [ 0.534, -0.806, 0.253, -0.275], [ 0.681, 0.234, -0.694, -0.067], [ 0.5 , 0.543, 0.674, -0.192], [ 0. , 0. , 0. , 1. ], [ 0. , -1. , -0. , 0.109], [ 1. , 0. , 0. , 0.297], [-0. , -0. , 1. , -0.254], [ 0. , 0. , 0. , 1. ]]) ''' R_start, p_start = TransToRp(X_start) #Just to ensure X_start is valid R_end ,p_end = TransToRp(X_end) #Just to ensure X_end is valid assert N >= 2, 'N must be >= 2' assert isinstance(N, int), 'N must be an integer' assert method == 'cubic' or method == 'quintic', 'Incorrect time-scaling method argument' trajectory = X_start if method == 'cubic': for i in range(1,N): t = i*float(T)/(N-1) s = CubicTimeScaling(T,t) X_s = X_start.dot(MatrixExp6(MatrixLog6(TransInv(X_start).dot(X_end))*s)) trajectory = vstack((trajectory, X_s)) return trajectory elif method == 'quintic': for i in range(1,N): t = i*float(T)/(N-1) s = QuinticTimeScaling(T,t) X_s = X_start.dot(MatrixExp6(MatrixLog6(TransInv(X_start).dot(X_end))*s)) trajectory = vstack((trajectory, X_s)) return trajectory def CartesianTrajectory(X_start, X_end, T, N, method='cubic'): ''' Similar to ScrewTrajectory, except the origin of the end-effector frame follows a straight line, decoupled from the rotational motion. Example: thetas_start = [0.1]*6 thetas_end = [pi/2]*6 M_ur5 = [[1,0,0,-.817],[0,0,-1,-.191],[0,1,0,-.006],[0,0,0,1]] S1_ur5 = [0,0,1,0,0,0] S2_ur5 = [0,-1,0,.089,0,0] S3_ur5 = [0,-1,0,.089,0,.425] S4_ur5 = [0,-1,0,.089,0,.817] S5_ur5 = [0,0,-1,.109,-.817,0] S6_ur5 = [0,-1,0,-.006,0,.817] Slist_ur5 = [S1_ur5,S2_ur5,S3_ur5,S4_ur5,S5_ur5,S6_ur5] X_start = FKinFixed(M_ur5, Slist_ur5, thetas_start) X_end = FKinFixed(M_ur5, Slist_ur5, thetas_end) T = 2 N = 3 CartesianTrajectory(X_start, X_end, T, N, 'quintic') >> array([[ 0.922, -0.388, 0.004, -0.764], [-0.007, -0.029, -1. , -0.268], [ 0.388, 0.921, -0.03 , -0.124], [ 0. , 0. , 0. , 1. ], [ 0.534, -0.806, 0.253, -0.327], [ 0.681, 0.234, -0.694, 0.014], [ 0.5 , 0.543, 0.674, -0.189], [ 0. , 0. , 0. , 1. ], [ 0. , -1. , -0. , 0.109], [ 1. , 0. , 0. , 0.297], [-0. , -0. , 1. , -0.254], [ 0. , 0. , 0. , 1. ]]) Notice the R of every T is same for ScrewTrajectory and CartesianTrajectory, but the translations are different. ''' R_start, p_start = TransToRp(X_start) R_end ,p_end = TransToRp(X_end) assert N >= 2, 'N must be >= 2' assert isinstance(N, int), 'N must be an integer' assert method == 'cubic' or method == 'quintic', 'Incorrect time-scaling method argument' trajectory = X_start if method == 'cubic': for i in range(1,N): t = i*float(T)/(N-1) s = CubicTimeScaling(T,t) p_s = (1-s)*p_start + s*p_end R_s = R_start.dot(MatrixExp3(MatrixLog3(RotInv(R_start).dot(R_end))*s)) X_s = RpToTrans(R_s, p_s) trajectory = vstack((trajectory, X_s)) return trajectory elif method == 'quintic': for i in range(1,N): t = i*float(T)/(N-1) s = QuinticTimeScaling(T,t) p_s = (1-s)*p_start + s*p_end R_s = R_start.dot(MatrixExp3(MatrixLog3(RotInv(R_start).dot(R_end))*s)) X_s = RpToTrans(R_s, p_s) trajectory = vstack((trajectory, X_s)) return trajectory ### end of HW4 functions ############################# ### start of HW5 functions ########################### def LieBracket(V1, V2): assert len(V1)==len(V2)==6, 'Needs two 6 vectors' V1.shape = (6,1) w1 = V1[:3,:] v1 = V1[3:,:] w1_mat = VecToso3(w1) v1_mat = VecToso3(v1) col1 = vstack((w1_mat, v1_mat)) col2 = vstack((zeros((3,3)), w1_mat)) mat1 = hstack((col1, col2)) return mat1.dot(V2) def TruthBracket(V1, V2): # Transposed version of Lie Bracket assert len(V1)==len(V2)==6, 'Needs two 6 vectors' V1.shape = (6,1) w1 = V1[:3,:] v1 = V1[3:,:] w1_mat = VecToso3(w1) v1_mat = VecToso3(v1) col1 = vstack((w1_mat, v1_mat)) col2 = vstack((zeros((3,3)), w1_mat)) mat1 = hstack((col1, col2)) return (mat1.T).dot(V2) def InverseDynamics(thetas, thetadots, thetadotdots, g, Ftip, M_rels, Glist, Slist): ''' M1 = array(([1.,0.,0.,0.],[0.,1.,0.,0.],[0.,0.,1.,0.],[0.,0.,.089159,1.])).T M2 = array(([0.,0.,-1.,0.],[0.,1.,0.,0.],[1.,0.,0.,0.],[.28,.13585,.089159,1.])).T M3 = array(([0.,0.,-1.,0.],[0.,1.,0.,0.],[1.,0.,0.,0.],[.675,.01615,.089159,1.])).T M4 = array(([-1.,0.,0.,0.],[0.,1.,0.,0.],[0.,0.,-1.,0.],[.81725,.01615,.089159,1.])).T M5 = array(([-1.,0.,0.,0.],[0.,1.,0.,0.],[0.,0.,-1.,0.],[.81725,.10915,.089159,1.])).T M6 = array(([-1.,0.,0.,0.],[0.,1.,0.,0.],[0.,0.,-1.,0.],[.81725,.10915,-.005491,1.])).T M01 = array(([1.,0.,0.,0.],[0.,1.,0.,0.],[0.,0.,1.,0.],[0.,0.,.089159,1.])).T M12 = array(([0.,0.,-1.,0.],[0.,1.,0.,0.],[1.,0.,0.,0.],[.28,.13585,0.,1.])).T M23 = array(([1.,0.,0.,0.],[0.,1.,0.,0.],[0.,0.,1.,0.],[0.,-.1197,.395,1])).T M34 = array(([0.,0.,-1.,0.],[0.,1.,0.,0.],[1.,0.,0.,0.],[0.,0.,.14225,1.])).T M45 = array(([1.,0.,0.,0.],[0.,1.,0.,0.],[0.,0.,1.,0.],[0.,.093,0.,1.])).T M56 = array(([1.,0.,0.,0.],[0.,1.,0.,0.],[0.,0.,1.,0.],[0.,0.,.09465,1.])).T G1 = array(([.010267,0.,0.,0.,0.,0.],[0.,.010267,0.,0.,0.,0.],[0.,0.,.00666,0.,0.,0.],[0.,0.,0.,3.7,0.,0.],[0.,0.,0.,0.,3.7,0.],[0.,0.,0.,0.,0.,3.7])) G2 = array(([.22689,0.,0.,0.,0.,0.],[0.,.22689,0.,0.,0.,0.],[0.,0.,.0151074,0.,0.,0.],[0.,0.,0.,8.393,0.,0.],[0.,0.,0.,0.,8.393,0.],[0.,0.,0.,0.,0.,8.393])) G3 = array(([.0494433,0.,0.,0.,0.,0.],[0.,.0494433,0.,0.,0.,0.],[0.,0.,.004095,0.,0.,0.],[0.,0.,0.,2.275,0.,0.],[0.,0.,0.,0.,2.275,0.],[0.,0.,0.,0.,0.,2.275])) G4 = array(([.111172,0.,0.,0.,0.,0.],[0.,.111172,0.,0.,0.,0.],[0.,0.,.21942,0.,0.,0.],[0.,0.,0.,1.219,0.,0.],[0.,0.,0.,0.,1.219,0.],[0.,0.,0.,0.,0.,1.219])) G5 = array(([.111172,0.,0.,0.,0.,0.],[0.,.111172,0.,0.,0.,0.],[0.,0.,.21942,0.,0.,0.],[0.,0.,0.,1.219,0.,0.],[0.,0.,0.,0.,1.219,0.],[0.,0.,0.,0.,0.,1.219])) G6 = array(([.0171364,0.,0.,0.,0.,0.],[0.,.0171364,0.,0.,0.,0.],[0.,0.,.033822,.0,0.,0.],[0.,0.,0.,.1879,0.,0.],[0.,0.,0.,0.,.1879,0.],[0.,0.,0.,0.,0.,.1879])) Slist = [[0.,0.,1.,0.,0.,0.],[0.,1.,0.,-.089,0.,0.],[0.,1.,0.,-.089,0.,.425],[0.,1.,0.,-.089,0.,.817],[0.,0.,-1.,-.109,.817,.0],[0.,1.,0.,.006,0.,.817]] Glist = [G1,G2,G3,G4,G5,G6] M_rels = [M01,M12,M23,M34,M45,M56] Ftip = [0.,0.,0.,0.,0.,0.] ''' assert len(thetas) == len(thetadots) == len(thetadotdots), 'Joint inputs mismatch' Slist = asarray(Slist) N = len(thetas) # no. of links Ftip = asarray(Ftip) # initialize iterables Mlist = [0]*N T_rels = [0]*N Vlist = [0]*N Vdotlist = [0]*N Alist = [0]*N Flist = [0]*N Taulist = [0]*N Mlist[0] = M_rels[0] for i in range(1, N): Mlist[i] = Mlist[i-1].dot(M_rels[i]) for i in range(N): Alist[i] = Adjoint(TransInv(Mlist[i])).dot(Slist[i]) for i in range(N): T_rels[i] = M_rels[i].dot(MatrixExp6(Alist[i]*thetas[i])) V0 = zeros((6,1)) Vlist[0] = V0 Vdot0 = -asarray([0,0,0]+g) Vdotlist[0] = Vdot0 F_ip1 = asarray(Ftip).reshape(6,1) # forward iterations for i in range(1, N): # print i T_i_im1 = TransInv(T_rels[i]) #### should it be i-1??? Vlist[i] = Adjoint(T_i_im1).dot(Vlist[i-1]) + (Alist[i]*thetadots[i]).reshape(6,1) Vdotlist[i] = Adjoint(T_i_im1).dot(Vdotlist[i-1]) + LieBracket(Vlist[i], Alist[i])*thetadots[i] + Alist[i]*thetadotdots[i] # print T_rels # print Vlist # print Vdotlist # print Alist # backward iterations for i in range(N-1,-1,-1): T_ip1_i = TransInv(T_rels[i]) Flist[i] = (Adjoint(T_ip1_i).T).dot(F_ip1) + (Glist[i].dot(Vdotlist[i])).reshape(6,1) - TruthBracket(Vlist[i], Glist[i].dot(Vlist[i])) Taulist[i] = (Flist[i].T).dot(Alist[i]) return asarray(Taulist).flatten() def InertiaMatrix(thetas, M_rels, Glist, Slist): Slist = asarray(Slist) N = len(thetas) # no. of links M = zeros((N,N)) for i in range(N): thetadotdots = [0]*N thetadotdots[i] = 1 M[:, i] = InverseDynamics(thetas, [0]*6, thetadotdots, [0]*3, [0]*6, M_rels, Glist, Slist) return M def CoriolisForces(thetas, thetadots, M_rels, Glist, Slist): C = InverseDynamics(thetas, thetadots, [0]*6, [0]*3, [0]*6, M_rels, Glist, Slist) return C def GravityForces(thetas, g, M_rels, Glist, Slist): Gvec = InverseDynamics(thetas, [0]*6, [0]*6, g, [0]*6, M_rels, Glist, Slist) return Gvec def EndEffectorForces(Ftip, thetas, M_rels, Glist, Slist): return InverseDynamics(thetas, [0]*6, [0]*6, [0]*3, Ftip, M_rels, Glist, Slist) def ForwardDynamics(thetas, thetadots, taus, g, Ftip, M_rels, Glist, Slist): M = InertiaMatrix(thetas, M_rels, Glist, Slist) C = CoriolisForces(thetas, thetadots, M_rels, Glist, Slist) Gvec = GravityForces(thetas, g, M_rels, Glist, Slist) eeF = EndEffectorForces(Ftip, thetas, M_rels, Glist, Slist) thetadotdots = (linalg.pinv(M)).dot(taus - C - Gvec - eeF) return thetadotdots def EulerStep(thetas_t, thetadots_t, thetadotdots_t, delt): thetas_t = asarray(thetas_t) thetadots_t = asarray(thetadots_t) thetadotdots_t = asarray(thetadotdots_t) thetas_next = thetas_t + delt*thetadots_t thetadots_next = thetadots_t + delt*thetadotdots_t return thetas_next, thetadots_next def InverseDynamicsTrajectory(thetas_traj, thetadots_traj, thetadotdots_traj, Ftip_traj, g, M_rels, Glist, Slist): Np1 = len(thetas_traj) # N = Np1-1 idtraj = [] for i in range(Np1): taus = InverseDynamics(thetas_traj[i], thetadots_traj[i], thetadotdots_traj[i], g, Ftip_traj[i], M_rels, Glist, Slist) idtraj.append(taus) return asarray(idtraj) def ForwardDynamicsTrajectory(thetas_init, thetadots_init, tau_hist, delt, g, Ftip_traj, M_rels, Glist, Slist): Np1 = len(tau_hist) thetas_traj = asarray(thetas_init) thetadots_traj = asarray(thetadots_init) for i in range(Np1): thetadotdots_init = ForwardDynamics(thetas_init, thetadots_init, tau_hist[i], g, Ftip_traj[i], M_rels, Glist, Slist) thetas_next, thetadots_next = EulerStep(thetas_init, thetadots_init, thetadotdots_init, delt) # append new state thetas_traj = hstack((thetas_traj, thetas_next)) thetadots_traj = hstack((thetadots_traj, thetadots_next)) # update initial conditions thetas_init = thetas_next thetadots_init = thetadots_next return thetas_traj.reshape(Np1+1, len(thetas_init)), thetadots_traj.reshape(Np1+1, len(thetas_init)) ### end of HW5 functions #############################

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/nonead/nUR-MCP-SERVER'

If you have feedback or need assistance with the MCP directory API, please join our Discord server