15
15
visualize = True
16
16
use_mesh = True
17
17
parallel = False
18
+ fknm_ = None
18
19
19
20
20
- def chomp ():
21
+ def jacob0_loop (robot , link , pts , qt = None ):
22
+ """
23
+ Non-parallel, use for loop
24
+ :param pts: (num, 3) xyz positions of pts
25
+ :param q: (cdim,) joint configurations
26
+ """
27
+ if qt is None :
28
+ qt = robot .q
29
+ jacob_vec = []
30
+ for pt in pts :
31
+ JJ = robot .jacob0 (qt , end = link , tool = SE3 (pt )) # (k, 6)
32
+ jacob_vec .append (JJ )
33
+ return np .array (jacob_vec )
34
+
35
+ def jacob0_vec (robot , link , pts , qt = None , verbose = False ):
36
+ """
37
+ Parallel, use CUDA
38
+ :param pts: (num, 3) xyz positions of pts
39
+ :param q: (cdim,) joint configurations
40
+ """
41
+ import ctypes as ct
42
+ global fknm_
43
+ if qt is None :
44
+ qt = robot .q
45
+ if fknm_ is None :
46
+ fknm_ = np .ctypeslib .load_library ('roboticstoolbox/cuda/fknm' ,'.' )
47
+ # Parallel, use cuda
48
+ t_start = time .time ()
49
+ num_pts = len (pts )
50
+ se3_pts = SE3 (pts )
51
+ pts_tool = np .array (se3_pts .A )
52
+ link_base = robot .fkine (qt , end = link )
53
+ print (f"1: { time .time () - t_start :.3f} \n " )
54
+ t_start = time .time ()
55
+ # pts_mat = np.array((link_base @ se3_pts).A)
56
+ pts_mat = np .array (link_base .A .dot (np .array (se3_pts .A )).swapaxes (0 , 1 ), order = 'C' )
57
+ e_pts = np .zeros ((num_pts , 3 ))
58
+ pts_etool = np .array (SE3 (e_pts ).A )
59
+ print (f"2: { time .time () - t_start :.3f} \n " )
60
+ t_start = time .time ()
61
+ link_As = []
62
+ link_axes = []
63
+ link_isjoint = []
64
+ path , njoints , _ = robot .get_path (end = link )
65
+ nlinks = len (path )
66
+ for il , link in enumerate (path ):
67
+ axis = get_axis (link )
68
+ link_As .append (link .A (qt [link .jindex ]).A )
69
+ link_axes .append (axis )
70
+ link_isjoint .append (link .isjoint )
71
+ link_As = np .array (link_As )
72
+ link_axes = np .array (link_axes , dtype = int )
73
+ link_isjoint = np .array (link_isjoint , dtype = int )
74
+ jacob_vec = np .zeros ((num_pts , 6 , njoints ))
75
+
76
+ if verbose :
77
+ print (f"pts shape { pts_mat .shape } " )
78
+ print (f"pts_tool shape { pts_tool .shape } " )
79
+ print (f"pts_etool shape { pts_etool .shape } " )
80
+ print (f"link_As shape { link_As .shape } " )
81
+ print (f"link_axes shape { link_axes .shape } " )
82
+ print (f"link_isjoint shape { link_isjoint .shape } " )
83
+ print (f"jacob_vec shape { jacob_vec .shape } " )
84
+ print (f"nlinks { nlinks } " )
85
+ print (f"njoints { njoints } " )
86
+ print (f"num_pts { num_pts } " )
87
+
88
+ fknm_ .jacob0 (pts_mat .ctypes .data_as (ct .c_void_p ),
89
+ pts_tool .ctypes .data_as (ct .c_void_p ),
90
+ pts_etool .ctypes .data_as (ct .c_void_p ),
91
+ # link_As.ctypes.data_as(ct.c_void_p),
92
+ ct .c_void_p (link_As .ctypes .data ),
93
+ link_axes .ctypes .data_as (ct .c_void_p ),
94
+ link_isjoint .ctypes .data_as (ct .c_void_p ),
95
+ ct .c_int (num_pts ),
96
+ ct .c_int (nlinks ),
97
+ ct .c_int (njoints ),
98
+ jacob_vec .ctypes .data_as (ct .c_void_p ))
99
+ return jacob_vec
100
+
101
+ def chomp (seed = 0 ):
102
+ np .random .seed (seed )
103
+
21
104
robot = rtb .models .DH .Panda () # load Mesh version (for collisions)
22
105
# robot = rtb.models.URDF.Panda() # load URDF version of the Panda (for visuals)
23
106
# print(robot)
@@ -87,10 +170,6 @@ def chomp():
87
170
AA /= dt * dt * (nq + 1 )
88
171
Ainv = np .linalg .pinv (AA )
89
172
90
- fknm_ = None
91
- if parallel :
92
- fknm_ = np .ctypeslib .load_library ('roboticstoolbox/cuda/fknm' ,'.' )
93
-
94
173
for t in range (iters ):
95
174
nabla_smooth = AA .dot (xi ) + bb
96
175
nabla_obs = np .zeros (xidim )
@@ -107,56 +186,54 @@ def chomp():
107
186
else :
108
187
qd = 0.5 * (xi [cdim * (i + 1 ): cdim * (i + 2 )] - xi [cdim * (i - 1 ): cdim * (i )])
109
188
110
- import pdb ; pdb .set_trace ()
189
+ # import pdb; pdb.set_trace()
111
190
for link in robot .links : # bodypart
112
191
k = link .jindex
113
192
if k is None :
114
193
continue
115
194
116
195
link_base = robot .fkine (robot .q , end = link ) # x_current, (4, 4)
117
196
delta_nabla_obs = np .zeros (k + 1 )
197
+ mesh = meshes [link .name ]
198
+ idxs = np .random .choice (np .arange (len (mesh .vertices )), num_pts , replace = False )
199
+ pts = mesh .vertices [idxs ]
200
+
118
201
if not parallel :
119
- # Non-parallel, use for loop
120
- mesh = meshes [link .name ]
121
- for j in range (num_pts ):
122
- # For each point: compute Jacobian, compute cost, compute cost gradient
123
-
124
- pt_rel = mesh .vertices [j ]
125
- pt_tool = link_base @ SE3 (pt_rel )
126
- pt_pos = pt_tool .t
127
-
128
- JJ = robot .jacob0 (qt , end = link , tool = SE3 (pt_rel )) # (k, 6)
129
- import pdb ; pdb .set_trace ()
130
- xd = JJ .dot (qd [:k + 1 ]) # x_delta
131
- vel = np .linalg .norm (xd )
132
-
133
- xdn = xd / (vel + 1e-3 ) # speed normalized
134
- xdd = JJ .dot (xidd [cdim * i : cdim * i + k + 1 ]) # second derivative of xi
135
- prj = np .eye (6 ) - xdn [:, None ].dot (xdn [:, None ].T ) # curvature vector (6, 6)
136
- kappa = (prj .dot (xdd ) / (vel ** 2 + 1e-3 )) # (6,)
137
-
138
- cost = np .sum (pt_pos )
139
- total_cost += cost / num_pts
140
- # delta := negative gradient of obstacle cost in work space, (6, cdim)
141
- delta = - 1 * np .concatenate ([[1 , 1 , 0 ], np .zeros (3 )])
142
- # for link in robot.links:
143
- # cost = get_link_cost(robot, meshes, link)
144
- delta_nabla_obs += JJ .T .dot (vel ).dot (prj .dot (delta ) - cost * kappa )
145
-
146
- nabla_obs [cdim * i : cdim * i + k + 1 ] += (delta_nabla_obs / num_pts )
202
+ jacobs = jacob0_loop (robot , link , pts , qt )
147
203
else :
148
- # Parallel, use cuda
149
- import ctypes as ct
150
- pt_rel = np .array (mesh .vertices [j ])
204
+ jacobs = jacob0_vec (robot , link , pts , qt )
205
+
206
+ # TODO: vectorize cost calculation
207
+ for j in range (num_pts ):
208
+ # For each point: compute Jacobian, compute cost, compute cost gradient
209
+ pt_rel = mesh .vertices [j ]
210
+ pt_tool = link_base @ SE3 (pt_rel )
211
+ pt_pos = pt_tool .t
212
+
213
+ JJ = robot .jacob0 (qt , end = link , tool = SE3 (pt_rel )) # (k, 6)
214
+ xd = JJ .dot (qd [:k + 1 ]) # x_delta
215
+ vel = np .linalg .norm (xd )
216
+ xdn = xd / (vel + 1e-3 ) # speed normalized
217
+ xdd = JJ .dot (xidd [cdim * i : cdim * i + k + 1 ]) # second derivative of xi
218
+ prj = np .eye (6 ) - xdn [:, None ].dot (xdn [:, None ].T ) # curvature vector (6, 6)
219
+ kappa = (prj .dot (xdd ) / (vel ** 2 + 1e-3 )) # (6,)
220
+
221
+ cost = np .sum (pt_pos )
222
+ total_cost += cost / num_pts
223
+ # delta := negative gradient of obstacle cost in work space, (6, cdim)
224
+ delta = - 1 * np .concatenate ([[1 , 1 , 0 ], np .zeros (3 )])
225
+ # for link in robot.links:
226
+ # cost = get_link_cost(robot, meshes, link)
227
+ delta_nabla_obs += JJ .T .dot (vel ).dot (prj .dot (delta ) - cost * kappa )
228
+
229
+ nabla_obs [cdim * i : cdim * i + k + 1 ] += (delta_nabla_obs / num_pts )
151
230
152
231
153
232
# dxi = Ainv.dot(lmbda * nabla_smooth)
154
233
dxi = Ainv .dot (nabla_obs + lmbda * nabla_smooth )
155
234
xi -= dxi / eta
156
235
print (f"Iteration { t } total cost { total_cost } " )
157
236
158
- # @vectorize(['float32(float32)'], target='cuda')
159
- # def vec_jacob0()
160
237
161
238
if visualize :
162
239
from roboticstoolbox .backends .swift import Swift # instantiate 3D browser-based visualizer
@@ -245,8 +322,8 @@ def test_parallel():
245
322
T = SE3 (0.7 , 0.2 , 0.1 ) * SE3 .OA ([0 , 1 , 0 ], [0 , 0 , - 1 ])
246
323
sol = robot .ikine_LM (T ) # solve IK
247
324
q_pickup = sol .q
248
- qtraj = rtb .jtraj (robot .qz , q_pickup , 50 )
249
325
robot = rtb .models .URDF .Panda () # load URDF version of the Panda
326
+ robot .q = q_pickup
250
327
meshes = {}
251
328
for link in robot .links :
252
329
if len (link .geometry ) != 1 :
@@ -264,86 +341,41 @@ def test_parallel():
264
341
lmbda = 1000
265
342
eta = 1000
266
343
iters = 4
267
- num_pts = 5000
344
+ num_pts = 2000
268
345
269
346
270
347
# Make cost field, starting & end points
271
- cdim = len (qtraj . q [ 0 ] )
348
+ cdim = len (robot . q )
272
349
xidim = cdim * nq
273
350
AA = np .zeros ((xidim , xidim ))
274
351
xi = np .zeros (xidim )
275
- robot ._set_link_fk (qtraj .q [1 ])
276
-
277
352
278
- link = robot .links [- 2 ]
279
- k = link .jindex
280
- link_base = robot .fkine (robot .q , end = link )
281
353
354
+ for idx in [2 , 3 , 4 , 5 , 6 , 7 ]:
355
+ print (f"Iidx { idx } " )
356
+ link = robot .links [idx ]
357
+ k = link .jindex
282
358
283
- # Non-parallel, use for loop
284
- mesh = meshes [link .name ]
285
- jacob_loop = []
286
- t_start = time .time ()
287
- for j in range (num_pts ):
288
- pt_rel = mesh .vertices [j ]
289
- JJ = robot .jacob0 (robot .q , end = link , tool = SE3 (pt_rel )) # (
290
- jacob_loop .append (JJ )
291
- jacob_loop = np .array (jacob_loop )
292
- print (f"\n Non-parallel time: { time .time () - t_start :.3f} \n " )
293
- # print(jacob_loop)
294
359
360
+ # Non-parallel, use for loop
361
+ mesh = meshes [link .name ]
362
+ pts = mesh .vertices [:num_pts ]
295
363
296
- # Parallel, use cuda
297
- import ctypes as ct
298
- fknm_ = np .ctypeslib .load_library ('roboticstoolbox/cuda/fknm' ,'.' )
299
- pts = np .array (meshes [link .name ].vertices [:num_pts ])
300
- pts_mat = np .array ((link_base @ SE3 (pts )).A )
301
- e_pts = np .zeros ((num_pts , 3 ))
302
- pts_tool = np .array (SE3 (pts ).A )
303
- pts_etool = np .array (SE3 (e_pts ).A )
304
- link_As = []
305
- link_axes = []
306
- link_isjoint = []
307
- path , njoints , _ = robot .get_path (end = link )
308
- nlinks = len (path )
364
+ t_start = time .time ()
365
+ jacobs1 = jacob0_loop (robot , link , pts )
366
+ print (f"\n Non-parallel time: { time .time () - t_start :.3f} \n " )
367
+ # print(jacobs1)
368
+ # Parallel, use cuda
369
+ t_start = time .time ()
370
+ jacobs2 = jacob0_vec (robot , link , pts , verbose = True )
371
+ print (f"\n Parallel time: { time .time () - t_start :.3f} \n " )
372
+ # print(jacobs2)
373
+ # print(f"Max diff 0 {np.max(np.abs(jacobs1[0] - jacobs2[0]))}")
374
+ # print(f"Max diff 0 {np.argmax(np.abs(jacobs1 - jacobs2))}")
375
+ # print(f"Max diff {np.max(np.abs(jacobs1 - jacobs2))}")
376
+ # import pdb; pdb.set_trace()
377
+ assert np .all (np .isclose (jacobs1 , jacobs2 ))
309
378
310
- for il , link in enumerate (path ):
311
- axis = get_axis (link )
312
- link_As .append (link .A ().A )
313
- link_axes .append (axis )
314
- link_isjoint .append (link .isjoint )
315
- link_As = np .array (link_As )
316
- link_axes = np .array (link_axes , dtype = int )
317
- link_isjoint = np .array (link_isjoint , dtype = int )
318
- jacob_vec = np .zeros ((num_pts , 6 , njoints ))
319
-
320
-
321
- print (f"pts shape { pts_mat .shape } " )
322
- print (f"pts_tool shape { pts_tool .shape } " )
323
- print (f"pts_etool shape { pts_etool .shape } " )
324
- print (f"link_As shape { link_As .shape } " )
325
- print (f"link_axes shape { link_axes .shape } " )
326
- print (f"link_isjoint shape { link_isjoint .shape } " )
327
- print (f"jacob_vec shape { jacob_vec .shape } " )
328
- print (f"nlinks { nlinks } " )
329
- print (f"njoints { njoints } " )
330
- print (f"num_pts { num_pts } " )
331
-
332
- t_start = time .time ()
333
- fknm_ .jacob0 (pts_mat .ctypes .data_as (ct .c_void_p ),
334
- pts_tool .ctypes .data_as (ct .c_void_p ),
335
- pts_etool .ctypes .data_as (ct .c_void_p ),
336
- # link_As.ctypes.data_as(ct.c_void_p),
337
- ct .c_void_p (link_As .ctypes .data ),
338
- link_axes .ctypes .data_as (ct .c_void_p ),
339
- link_isjoint .ctypes .data_as (ct .c_void_p ),
340
- ct .c_int (num_pts ),
341
- ct .c_int (nlinks ),
342
- ct .c_int (njoints ),
343
- jacob_vec .ctypes .data_as (ct .c_void_p ))
344
- print (f"\n Parallel time: { time .time () - t_start :.3f} \n " )
345
- # print(jacob_vec)
346
- assert np .all (np .isclose (jacob_loop , jacob_vec ))
347
379
348
380
def get_axis (link ):
349
381
axis = None
0 commit comments