11import numpy as np # type: ignore
22import attr
3- from typing import Any , Optional , Sequence , Sized , Union , Iterable , Dict , List
3+ # from typing import Any, Optional, Sequence, Sized, Union, Iterable, Dict, List
44# import scipy # type: ignore
55import scipy .optimize # type: ignore
66# from numpy.linalg import norm
@@ -21,12 +21,16 @@ class UnReachable(Exception):
2121 pass
2222
2323@attr .s
24- class KinematicChain (Sized , Iterable ):
25- _links = attr .ib (type = Sequence [Any ])
24+ # class KinematicChain(Sized, Iterable):
25+ class KinematicChain :
26+ # _links = attr.ib(type=Sequence[Any])
27+ _links = attr .ib ()
28+ _size = attr .ib ()
2629
2730 def __len__ (self ):
2831 """Enables the length function, returns number links"""
29- return len (self ._links )
32+ # return len(self._links)
33+ return self ._size
3034
3135 def __iter__ (self ):
3236 """Enables iteration of joints: for j in chain: print(j)"""
@@ -39,8 +43,8 @@ def __getitem__(self, key):
3943
4044 def transform (self , joints ):
4145 """Calculates the transformation and returns a 4x4 matrix"""
42- if len (joints ) != len ( self ._links ) :
43- raise Exception ("inputs don't equal number of links" )
46+ if len (joints ) != self .size :
47+ raise Exception (f "inputs don't equal number of links { len ( joints ) } != { self . size } " )
4448
4549 t = np .eye (4 )
4650 for l , q in zip (reversed (self ._links ), reversed (joints )):
@@ -63,14 +67,14 @@ def inverse(self, pos):
6367
6468 FIXME: this only works for when the foot is straight down
6569 """
66- j = [[],[]] # type: Sequence[List]
70+ joint_limits = [[],[]] # type: Sequence[List]
6771 for l in self :
68- j [0 ].append (l .min )
69- j [1 ].append (l .max )
70- # j[0][3] = -0.00001
71- # j[1][3] = 0.00001
72-
73- joint_limits = np .array (j ) # type: np.ndarray
72+ joint_limits [0 ].append (l .min )
73+ joint_limits [1 ].append (l .max )
74+ # # j[0][3] = -0.00001
75+ # # j[1][3] = 0.00001
76+ # joint_limits = j
77+ # joint_limits = np.array(j) # type: np.ndarray
7478 # print(joint_limits)
7579
7680 # r = R.from_matrix([[1,0,0],[0,0,-1],[0,1,0]])
@@ -79,65 +83,81 @@ def inverse(self, pos):
7983
8084 # make desired transform pose (position, oritentation)
8185 # change the -90 x-axis to something else for non-down??
82- x = pos [0 ]
83- y = pos [1 ]
84- c = R .from_euler ('zyx' , [- 90 ,atan2 (y ,x )* 180 / pi ,90 ], degrees = True )
85- ppos = np .eye (4 )
86- ppos [:3 ,:3 ] = c .as_matrix ()
87- ppos [:3 , 3 ] = pos
86+ # x = pos[0]
87+ # y = pos[1]
88+ # c = R.from_euler('zyx', [-90,atan2(y,x)*180/pi,90], degrees=True)
89+ # ppos = np.eye(4)
90+ # ppos[:3,:3] = c.as_matrix()
91+ # ppos[:3, 3] = pos
8892
8993 start = [0 ]* len (self ._links )
9094
9195 result = scipy .optimize .least_squares (
9296 fun = _ik_cost_function ,
9397 x0 = np .array (start ),
9498 bounds = joint_limits ,
95- args = (ppos , self )
96- ) # type: scipy.optimize.OptimizeResult
99+ args = (pos , self )
100+ )
97101
98102 if not result .success : # pragma: no cover
99103 raise UnReachable (f"Can't reach: { pos } m" )
100104 # print(">> yeah!!!")
101105 # print(">>", np.rad2deg(result.x))
102106 actual_t = self .transform (result .x )
103- actual_pos = actual_t [:3 ,3 ]
107+ actual_pos = actual_t #actual_t [:3,3]
104108 if np .allclose (actual_pos , pos , atol = 1e-3 ):
105109 # print(result)
106110 return result .x
107111
108112 raise UnReachable (f"Can't reach: { pos } " )
109113
114+ @property
115+ def size (self ):
116+ return self ._size
117+
110118 @classmethod
111119 def from_parameters (cls , params ):
112120 """Builds a KinematicChain object from an input"""
113121 links = []
122+ size = 0
114123 for l in params :
115124 if not isinstance (l , dict ):
116125 raise Exception (f"Invalid parameters: { l } " )
117126
118- for key in ['alpha' , 'a' , 'theta' , 'd' , 'type' ]:
127+ for key in ['alpha' , 'a' , 'theta' , 'd' ]:
119128 if key not in l :
120129 raise Exception (f"Missing parameter: { key } " )
121130
122- ll = mdh_params (l ['alpha' ], l ['a' ], l ['theta' ], l ['d' ], l ['type' ])
123-
124- if ll .type == JointType .revolute :
125- link = RevoluteLink (a = ll .a , alpha = ll .alpha , d = ll .d , theta = ll .theta )
126- elif ll .type == JointType .prismatic :
127- raise NotImplementedError (f"from_parameters: { l .type } " )
128- else :
129- raise Exception (f"Invalid parameter: { l .type } " )
130-
131- if "max_min" in l :
132- link .min = l ["max_min" ][1 ]
133- link .max = l ["max_min" ][0 ]
134- else :
135- link .min = - pi
136- link .max = pi
131+ # ll = mdh_params(l['alpha'], l['a'], l['theta'], l['d'])
132+ # print(f">> params: {ll}")
133+ # print(l['alpha'])
134+
135+ # if ll.type == JointType.revolute:
136+ # link = RevoluteLink(a=ll.a, alpha=ll.alpha, d=ll.d, theta=ll.theta)
137+ # link = RevoluteLink(alpha=ll.alpha, a=ll.a, theta=ll.theta, d=ll.d)
138+ link = RevoluteLink (l ['alpha' ], l ['a' ], l ['theta' ], l ['d' ])
139+ # elif ll.type == JointType.prismatic:
140+ # raise NotImplementedError(f"from_parameters: {l.type}")
141+ # else:
142+ # raise Exception(f"Invalid parameter: {l.type}")
143+
144+ # if "max_min" in l:
145+ # link.min = l["max_min"][1]
146+ # link.max = l["max_min"][0]
147+ # else:
148+ link .min = - pi
149+ link .max = pi
137150
138151 links .append (link )
139152
140- ret = cls (links )
153+ # if 'fixed' in l:
154+ # if l['fixed'] is not True:
155+ # size += 1
156+ # else:
157+ # size += 1
158+ size += 1
159+
160+ ret = cls (links , size )
141161
142162 return ret
143163
0 commit comments