Matrix - Py Matrix Class For Matrix
Matrix - Py Matrix Class For Matrix
"""
# Built for STEWART FORCE>..
import random
import operator
import sys
import unittest
import numpy as np
__version__ = "0.47"
print('Stewart Platform API v0.47\n');
def rotation_z(angleZ):
sinZ = sin(angleZ)
cosZ = cos(angleZ)
class MatrixError(Exception):
""" An exception class for Matrix """
pass
class Matrix(object):
""" A simple Python matrix class with
basic operations and operator overloading """
def __str__(self):
s = '\n'.join([' '.join([str(item) for item in row]) for row in self.rows])
return s + '\n'
def __repr__(self):
s = str(self.rows)
rank = str(self.getRank())
rep = "Matrix: \"%s\", rank: \"%s\"" % (s, rank)
return rep
def reset(self):
""" Reset the matrix data """
self.rows = [[] for x in range(self.m)]
return self;
def transpose(self):
""" Transpose the matrix. Changes the current matrix """
def getTranspose(self):
""" Return a transpose of the matrix without
modifying the matrix itself """
m, n = self.n, self.m
mat = Matrix(m, n)
mat.rows = [list(item) for item in zip(*self.rows)]
return mat
def getRank(self):
return (self.m, self.n)
if self.getRank() != mat.getRank():
raise MatrixError("Trying to add matrixes of varying rank!")
ret = Matrix(self.m, self.n)
for x in range(self.m):
row = [sum(item) for item in zip(self.rows[x], mat[x])]
ret[x] = row
return ret
if self.getRank() != mat.getRank():
raise MatrixError("Trying to add matrixes of varying rank!")
for x in range(self.m):
row = [item[0] - item[1] for item in zip(self.rows[x], mat[x])]
ret[x] = row
return ret
if (self.n != mat.m):
raise MatrixError("Matrices cannot be multipled!")
mat_t = mat.getTranspose()
mulmat = Matrix(self.m, matn)
for x in range(self.m):
for y in range(mat_t.m):
mulmat[x][y] = sum([item[0] * item[1] for item in zip(self.rows[x],
mat_t[y])])
return mulmat
# Calls __add__
tempmat = self + mat
self.rows = tempmat.rows[:]
return self
# Calls __sub__
tempmat = self - mat
self.rows = tempmat.rows[:]
return self
# Calls __mul__
tempmat = self * mat
self.rows = tempmat.rows[:]
self.m, self.n = tempmat.getRank()
return self
@classmethod
def _makeMatrix(cls, rows):
m = len(rows)
n = len(rows[0])
# Validity check
if any([len(row) != n for row in rows[1:]]):
raise MatrixError("inconsistent row length")
mat = Matrix(m, n, init=False)
mat.rows = rows
return mat
@classmethod
def makeRandom(cls, m, n, low=0, high=10):
""" Make a random matrix with elements in range (low-high) """
return obj
@classmethod
def makeZero(cls, m, n):
""" Make a zero-matrix of rank (mxn) """
@classmethod
def makeDiagonal(cls, m, n):
""" Make a diagonal matrix (mxn) """
if m != n:
raise MatrixError("Only sqaure matrices can be made diagonal")
rows = cls.makeZero(m, n)
for i in range(m): rows[i][i] = 1
return cls.fromList(rows)
@classmethod
def makeId(cls, m):
""" Make identity matrix of rank (mxm) """
return cls.fromList(rows)
@classmethod
def readStdin(cls):
""" Read a matrix from standard input """
return cls._makeMatrix(rows)
@classmethod
def readGrid(cls, fname):
""" Read a matrix from a file """
rows = []
for line in open(fname).readlines():
row = [int(x) for x in line.split()]
rows.append(row)
return cls._makeMatrix(rows)
@classmethod
def fromList(cls, listoflists):
""" Create a matrix by directly passing a list
of lists """
rows = listoflists[:]
return cls._makeMatrix(rows)
def wait(s):
sleep(s)
def map(x, in_min, in_max, out_min, out_max):
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
class Actuators:
def __init__(self, port='COM14', baudrate=1000000):
self.portHandler = PortHandler(port)
self.packetHandler = PacketHandler(1.0)
self.groupSyncWrite = GroupSyncWrite(self.portHandler, self.packetHandler,
30, 4)
self.portHandler.openPort()
self.portHandler.setBaudRate(baudrate)
wait(1)
if len(self.ping()) < 6:
raise Exception('Actuators Count Error')
for i in range(len(goal_positions)):
dxl_addparam_result = self.groupSyncWrite.addParam(i + 1,
goal_positions[i])
if dxl_addparam_result != True:
print('False')
self.groupSyncWrite.txPacket()
self.groupSyncWrite.clearParam()
# Depreciated
def set_moving_speed(self, speed):
for i in range(1, 7):
self.set_goal_speed_single(i, speed[i - 1])
# Depreciated
def set_goal_position_single(self, id, pos):
self.packetHandler.write2ByteTxRx(self.portHandler, id, 30, int(
round(map(((90 - pos) if id % 2 != 0 else (90 + pos)), -90, 90, 0,
2048))))
# Depreciated
def set_goal_speed_single(self, id, speed):
self.packetHandler.write2ByteTxRx(self.portHandler, id, 32, speed)
def ping(self):
found_ids = []
for i in range(1, 10):
dxl_model_number, dxl_comm_result, dxl_error =
self.packetHandler.ping(self.portHandler, i)
if dxl_comm_result == COMM_SUCCESS:
found_ids.append(i)
return found_ids
def close(self):
self.portHandler.closePort()
def rad(deg):
return deg / 180.0 * pi
def deg(rad):
return rad * 180.0 / pi
class Robot:
motorH = 102.30
HOME_Z = 295.92
RELATIVE = 'rel'
ABSOLUTE = 'abs'
x, y, z, roll, pitch, yaw = 0, 0, HOME_Z, 0, 0, 0
LINK_1 = 80.0
LINK_2 = 220.0
platform = np.array(
[[23.56, 141.78, 0, 1], [-23.56, 141.78, 0, 1], [-134.57, -50.49, 0, 1], [-
110.77, -91.59, 0, 1],
[110.77, -91.59, 0, 1], [134.57, -50.49, 0, 1]])
base = np.array([[58.66, 144.14, 0, 1], [-58.66, 144.14, 0, 1], [-154.15, -
21.27, 0, 1], [-95.5, -122.86, 0, 1],
[95.5, -122.86, 0, 1], [154.15, -21.27, 1]])
self.LINK_1 = LINK_1
self.LINK_2 = LINK_2
self.link_1_correction = link_1_correction
self.link_2_correction = link_2_correction
def close(self):
self.actuators.close()
def reset(self):
self.goto()
hs = self.platform
sh = self.base
# Applying transformation
hs = np.matmul(hs, translation(-self.tool_x, -self.tool_y, -self.tool_z))
hs = np.matmul(hs, rotation(rad(self.roll), rad(self.pitch),
rad(self.yaw)))
hs = np.matmul(hs, translation(self.tool_x, self.tool_y, self.tool_z))
hs = np.matmul(hs, translation(self.x, self.y, self.z - self.motorH))
# iKin
l1o = np.array([[hs[0][0] - sh[0][0]], [hs[0][1] - sh[0][1]], [hs[0][2] -
sh[0][2]]])
l2o = np.array([[hs[1][0] - sh[1][0]], [hs[1][1] - sh[1][1]], [hs[1][2] -
sh[1][2]]])
l3o = np.array([[hs[2][0] - sh[2][0]], [hs[2][1] - sh[2][1]], [hs[2][2] -
sh[2][2]]])
l4o = np.array([[hs[3][0] - sh[3][0]], [hs[3][1] - sh[3][1]], [hs[3][2] -
sh[3][2]]])
l5o = np.array([[hs[4][0] - sh[4][0]], [hs[4][1] - sh[4][1]], [hs[4][2] -
sh[4][2]]])
l6o = np.array([[hs[5][0] - sh[5][0]], [hs[5][1] - sh[5][1]], [hs[5][2] -
sh[5][2]]])
l1 = np.matmul(rotation_z(rad(-150)).transpose(), l1o)
l2 = np.matmul(rotation_z(rad(150)).transpose(), l2o)
l3 = np.matmul(rotation_z(rad(-30)).transpose(), l3o)
l4 = np.matmul(rotation_z(rad(-90)).transpose(), l4o)
l5 = np.matmul(rotation_z(rad(90)).transpose(), l5o)
l6 = np.matmul(rotation_z(rad(30)).transpose(), l6o)
A1 = sqrt(
(link1[0] + link2[0] * cos(thetav1) * cos(theta21)) ** 2 + (link2[0] *
cos(thetav1) * sin(theta21)) ** 2);
A2 = sqrt(
(link1[1] + link2[1] * cos(thetav2) * cos(theta22)) ** 2 + (link2[1] *
cos(thetav2) * sin(theta22)) ** 2);
A3 = sqrt(
(link1[2] + link2[2] * cos(thetav3) * cos(theta23)) ** 2 + (link2[2] *
cos(thetav3) * sin(theta23)) ** 2);
A4 = sqrt(
(link1[3] + link2[3] * cos(thetav4) * cos(theta24)) ** 2 + (link2[3] *
cos(thetav4) * sin(theta24)) ** 2);
A5 = sqrt(
(link1[4] + link2[4] * cos(thetav5) * cos(theta25)) ** 2 + (link2[4] *
cos(thetav5) * sin(theta25)) ** 2);
A6 = sqrt(
(link1[5] + link2[5] * cos(thetav6) * cos(theta26)) ** 2 + (link2[5] *
cos(thetav6) * sin(theta26)) ** 2);
def update(self):
self.goto(self.x, self.y, self.z, self.roll, self.pitch, self.yaw)
def move_relative(self, x=0, y=0, z=0, roll=0, pitch=0, yaw=0, T=2, steps=100):
dx, dy, dz, droll, dpitch, dyaw = x / steps, y / steps, z / steps, roll /
steps, pitch / steps, yaw / steps
for i in tqdm(range(steps)):
self.move(x=dx, y=dy, z=dz, roll=droll, pitch=dpitch, yaw=dyaw)
wait(T / steps)