16
16
// forward defines
17
17
static PyObject * fkine_all (PyObject * self , PyObject * args );
18
18
static PyObject * jacob0 (PyObject * self , PyObject * args );
19
+ static PyObject * jacobe (PyObject * self , PyObject * args );
19
20
static PyObject * fkine (PyObject * self , PyObject * args );
20
21
static PyObject * link_init (PyObject * self , PyObject * args );
21
22
static PyObject * link_A (PyObject * self , PyObject * args );
22
23
static PyObject * link_update (PyObject * self , PyObject * args );
23
24
static PyObject * compose (PyObject * self , PyObject * args );
24
25
25
26
void _jacob0 (PyObject * links , int m , int n , npy_float64 * q , npy_float64 * etool , npy_float64 * tool , npy_float64 * J );
27
+ void _jacobe (PyObject * links , int m , int n , npy_float64 * q , npy_float64 * etool , npy_float64 * tool , npy_float64 * J );
26
28
void _fkine (PyObject * links , int n , npy_float64 * q , npy_float64 * etool , npy_float64 * tool , npy_float64 * ret );
27
29
void A (Link * link , npy_float64 * ret , double eta );
28
30
void mult (npy_float64 * A , npy_float64 * B , npy_float64 * C );
@@ -61,6 +63,10 @@ static PyMethodDef fknmMethods[] = {
61
63
(PyCFunction )jacob0 ,
62
64
METH_VARARGS ,
63
65
"Link" },
66
+ {"jacobe" ,
67
+ (PyCFunction )jacobe ,
68
+ METH_VARARGS ,
69
+ "Link" },
64
70
{"fkine_all" ,
65
71
(PyCFunction )fkine_all ,
66
72
METH_VARARGS ,
@@ -85,8 +91,7 @@ PyMODINIT_FUNC PyInit_fknm(void)
85
91
static PyObject * fkine_all (PyObject * self , PyObject * args )
86
92
{
87
93
Link * link ;
88
- npy_float64 * q , * base , * fk , * pfk , * ret ;
89
- npy_float64 * s_base ;
94
+ npy_float64 * q , * base , * ret ;
90
95
PyArrayObject * py_q , * py_base ;
91
96
PyObject * links , * iter_links ;
92
97
int m ;
@@ -115,34 +120,56 @@ static PyObject *fkine_all(PyObject *self, PyObject *args)
115
120
// Calculate the current link transform
116
121
A (link , ret , q [link -> jindex ]);
117
122
118
- // Get pointer to link._fk array
119
- fk = (npy_float64 * )PyArray_DATA (link -> fk );
120
-
121
123
if (link -> parent )
122
124
{
123
- // Get pointer to link.parent._fk array
124
- pfk = (npy_float64 * )PyArray_DATA (link -> parent -> fk );
125
-
126
125
// Multiply parent._fk by link.A and store in link._fk
127
- mult (pfk , ret , fk );
126
+ mult (link -> parent -> fk , ret , link -> fk );
128
127
}
129
128
else
130
129
{
131
130
// Multiply base by link.A and store in link._fk
132
- mult (base , ret , fk );
131
+ mult (base , ret , link -> fk );
133
132
}
134
133
135
134
// Set dependant shapes
136
135
for (int i = 0 ; i < link -> n_shapes ; i ++ )
137
136
{
138
- copy (fk , link -> shape_wT [i ]);
139
- mult (fk , link -> shape_base [i ], link -> shape_sT [i ]);
137
+ copy (link -> fk , link -> shape_wT [i ]);
138
+ mult (link -> fk , link -> shape_base [i ], link -> shape_sT [i ]);
140
139
}
141
140
}
142
141
143
142
Py_RETURN_NONE ;
144
143
}
145
144
145
+ static PyObject * jacobe (PyObject * self , PyObject * args )
146
+ {
147
+ npy_float64 * J , * q , * etool , * tool ;
148
+ PyArrayObject * py_J , * py_q , * py_tool , * py_etool ;
149
+ PyObject * links ;
150
+ int m , n ;
151
+
152
+ if (!PyArg_ParseTuple (
153
+ args , "iiOO!O!O!O!" ,
154
+ & m ,
155
+ & n ,
156
+ & links ,
157
+ & PyArray_Type , & py_q ,
158
+ & PyArray_Type , & py_etool ,
159
+ & PyArray_Type , & py_tool ,
160
+ & PyArray_Type , & py_J ))
161
+ return NULL ;
162
+
163
+ q = (npy_float64 * )PyArray_DATA (py_q );
164
+ J = (npy_float64 * )PyArray_DATA (py_J );
165
+ tool = (npy_float64 * )PyArray_DATA (py_tool );
166
+ etool = (npy_float64 * )PyArray_DATA (py_etool );
167
+
168
+ _jacobe (links , m , n , q , etool , tool , J );
169
+
170
+ Py_RETURN_NONE ;
171
+ }
172
+
146
173
static PyObject * jacob0 (PyObject * self , PyObject * args )
147
174
{
148
175
npy_float64 * J , * q , * etool , * tool ;
@@ -207,7 +234,7 @@ static PyObject *link_init(PyObject *self, PyObject *args)
207
234
PyObject * py_shape_base , * py_shape_wT , * py_shape_sT ;
208
235
PyObject * iter_base , * iter_wT , * iter_sT ;
209
236
PyArrayObject * pys_base , * pys_wT , * pys_sT ;
210
- npy_float64 * s_base , * s_wT , * s_sT ;
237
+ PyArrayObject * py_A , * py_fk ;
211
238
212
239
link = (Link * )PyMem_RawMalloc (sizeof (Link ));
213
240
@@ -217,8 +244,8 @@ static PyObject *link_init(PyObject *self, PyObject *args)
217
244
& jointtype ,
218
245
& link -> jindex ,
219
246
& link -> n_shapes ,
220
- & PyArray_Type , & link -> A ,
221
- & PyArray_Type , & link -> fk ,
247
+ & PyArray_Type , & py_A ,
248
+ & PyArray_Type , & py_fk ,
222
249
& py_shape_base ,
223
250
& py_shape_wT ,
224
251
& py_shape_sT ,
@@ -234,14 +261,17 @@ static PyObject *link_init(PyObject *self, PyObject *args)
234
261
return NULL ;
235
262
}
236
263
264
+ link -> A = (npy_float64 * )PyArray_DATA (py_A );
265
+ link -> fk = (npy_float64 * )PyArray_DATA (py_fk );
266
+
237
267
// Set shape pointers
238
268
iter_base = PyObject_GetIter (py_shape_base );
239
269
iter_wT = PyObject_GetIter (py_shape_wT );
240
270
iter_sT = PyObject_GetIter (py_shape_sT );
241
271
242
- link -> shape_base = (npy_float64 * )PyMem_RawCalloc (link -> n_shapes , sizeof (npy_float64 ));
243
- link -> shape_wT = (npy_float64 * )PyMem_RawCalloc (link -> n_shapes , sizeof (npy_float64 ));
244
- link -> shape_sT = (npy_float64 * )PyMem_RawCalloc (link -> n_shapes , sizeof (npy_float64 ));
272
+ link -> shape_base = (npy_float64 * * )PyMem_RawCalloc (link -> n_shapes , sizeof (npy_float64 ));
273
+ link -> shape_wT = (npy_float64 * * )PyMem_RawCalloc (link -> n_shapes , sizeof (npy_float64 ));
274
+ link -> shape_sT = (npy_float64 * * )PyMem_RawCalloc (link -> n_shapes , sizeof (npy_float64 ));
245
275
246
276
for (int i = 0 ; i < link -> n_shapes ; i ++ )
247
277
{
@@ -294,12 +324,11 @@ static PyObject *link_update(PyObject *self, PyObject *args)
294
324
int isjoint , isflip ;
295
325
int jointtype , jindex , n_shapes ;
296
326
PyObject * lo , * py_parent ;
297
- PyArrayObject * A , * fk ;
327
+ PyArrayObject * py_A , * py_fk ;
298
328
299
329
PyObject * py_shape_base , * py_shape_wT , * py_shape_sT ;
300
330
PyObject * iter_base , * iter_wT , * iter_sT ;
301
331
PyArrayObject * pys_base , * pys_wT , * pys_sT ;
302
- npy_float64 * s_base , * s_wT , * s_sT ;
303
332
304
333
if (!PyArg_ParseTuple (args , "OiiiiiO!O!OOOO" ,
305
334
& lo ,
@@ -308,8 +337,8 @@ static PyObject *link_update(PyObject *self, PyObject *args)
308
337
& jointtype ,
309
338
& jindex ,
310
339
& n_shapes ,
311
- & PyArray_Type , & A ,
312
- & PyArray_Type , & fk ,
340
+ & PyArray_Type , & py_A ,
341
+ & PyArray_Type , & py_fk ,
313
342
& py_shape_base ,
314
343
& py_shape_wT ,
315
344
& py_shape_sT ,
@@ -335,9 +364,9 @@ static PyObject *link_update(PyObject *self, PyObject *args)
335
364
iter_wT = PyObject_GetIter (py_shape_wT );
336
365
iter_sT = PyObject_GetIter (py_shape_sT );
337
366
338
- link -> shape_base = (npy_float64 * )PyMem_RawCalloc (n_shapes , sizeof (npy_float64 ));
339
- link -> shape_wT = (npy_float64 * )PyMem_RawCalloc (n_shapes , sizeof (npy_float64 ));
340
- link -> shape_sT = (npy_float64 * )PyMem_RawCalloc (n_shapes , sizeof (npy_float64 ));
367
+ link -> shape_base = (npy_float64 * * )PyMem_RawCalloc (n_shapes , sizeof (npy_float64 ));
368
+ link -> shape_wT = (npy_float64 * * )PyMem_RawCalloc (n_shapes , sizeof (npy_float64 ));
369
+ link -> shape_sT = (npy_float64 * * )PyMem_RawCalloc (n_shapes , sizeof (npy_float64 ));
341
370
342
371
for (int i = 0 ; i < n_shapes ; i ++ )
343
372
{
@@ -352,11 +381,6 @@ static PyObject *link_update(PyObject *self, PyObject *args)
352
381
link -> shape_sT [i ] = (npy_float64 * )PyArray_DATA (pys_sT );
353
382
}
354
383
355
- // if (n_shapes > 2)
356
- // {
357
- // copy(link->shape_base[0], link->shape_base[1]);
358
- // }
359
-
360
384
if (jointtype == 0 )
361
385
{
362
386
link -> op = rx ;
@@ -384,8 +408,8 @@ static PyObject *link_update(PyObject *self, PyObject *args)
384
408
385
409
link -> isjoint = isjoint ;
386
410
link -> isflip = isflip ;
387
- link -> A = A ;
388
- link -> fk = fk ;
411
+ link -> A = ( npy_float64 * ) PyArray_DATA ( py_A ) ;
412
+ link -> fk = ( npy_float64 * ) PyArray_DATA ( py_fk ) ;
389
413
link -> jindex = jindex ;
390
414
link -> axis = jointtype ;
391
415
link -> parent = parent ;
@@ -435,6 +459,104 @@ static PyObject *compose(PyObject *self, PyObject *args)
435
459
Py_RETURN_NONE ;
436
460
}
437
461
462
+ void _jacobe (PyObject * links , int m , int n , npy_float64 * q , npy_float64 * etool , npy_float64 * tool , npy_float64 * J )
463
+ {
464
+ Link * link ;
465
+ npy_float64 * T = (npy_float64 * )PyMem_RawCalloc (16 , sizeof (npy_float64 ));
466
+ npy_float64 * U = (npy_float64 * )PyMem_RawCalloc (16 , sizeof (npy_float64 ));
467
+ npy_float64 * temp = (npy_float64 * )PyMem_RawCalloc (16 , sizeof (npy_float64 ));
468
+ npy_float64 * ret = (npy_float64 * )PyMem_RawCalloc (16 , sizeof (npy_float64 ));
469
+ npy_float64 * invU = (npy_float64 * )PyMem_RawCalloc (16 , sizeof (npy_float64 ));
470
+ int j = n - 1 ;
471
+
472
+ _eye (U );
473
+ _fkine (links , m , q , etool , tool , T );
474
+
475
+ PyList_Reverse (links );
476
+ PyObject * iter_links = PyObject_GetIter (links );
477
+
478
+ mult (etool , U , temp );
479
+ copy (temp , U );
480
+ mult (tool , U , temp );
481
+ copy (temp , U );
482
+
483
+ for (int i = 0 ; i < m ; i ++ )
484
+ {
485
+ if (!(link = (Link * )PyCapsule_GetPointer (PyIter_Next (iter_links ), "Link" )))
486
+ return ;
487
+
488
+ if (link -> isjoint )
489
+ {
490
+ if (link -> axis == 0 )
491
+ {
492
+ J [0 * n + j ] = U [2 * 4 + 0 ] * U [1 * 4 + 3 ] - U [1 * 4 + 0 ] * U [2 * 4 + 3 ];
493
+ J [1 * n + j ] = U [2 * 4 + 1 ] * U [1 * 4 + 3 ] - U [1 * 4 + 1 ] * U [2 * 4 + 3 ];
494
+ J [2 * n + j ] = U [2 * 4 + 2 ] * U [1 * 4 + 3 ] - U [1 * 4 + 2 ] * U [2 * 4 + 3 ];
495
+ J [3 * n + j ] = U [0 * 4 + 0 ];
496
+ J [4 * n + j ] = U [0 * 4 + 1 ];
497
+ J [5 * n + j ] = U [0 * 4 + 2 ];
498
+ }
499
+ else if (link -> axis == 1 )
500
+ {
501
+ J [0 * n + j ] = U [0 * 4 + 0 ] * U [2 * 4 + 3 ] - U [2 * 4 + 0 ] * U [0 * 4 + 3 ];
502
+ J [1 * n + j ] = U [0 * 4 + 1 ] * U [2 * 4 + 3 ] - U [2 * 4 + 1 ] * U [0 * 4 + 3 ];
503
+ J [2 * n + j ] = U [0 * 4 + 2 ] * U [2 * 4 + 3 ] - U [2 * 4 + 2 ] * U [0 * 4 + 3 ];
504
+ J [3 * n + j ] = U [1 * 4 + 0 ];
505
+ J [4 * n + j ] = U [1 * 4 + 1 ];
506
+ J [5 * n + j ] = U [1 * 4 + 2 ];
507
+ }
508
+ else if (link -> axis == 2 )
509
+ {
510
+ J [0 * n + j ] = U [1 * 4 + 0 ] * U [0 * 4 + 3 ] - U [0 * 4 + 0 ] * U [1 * 4 + 3 ];
511
+ J [1 * n + j ] = U [1 * 4 + 1 ] * U [0 * 4 + 3 ] - U [0 * 4 + 1 ] * U [1 * 4 + 3 ];
512
+ J [2 * n + j ] = U [1 * 4 + 2 ] * U [0 * 4 + 3 ] - U [0 * 4 + 2 ] * U [1 * 4 + 3 ];
513
+ J [3 * n + j ] = U [2 * 4 + 0 ];
514
+ J [4 * n + j ] = U [2 * 4 + 1 ];
515
+ J [5 * n + j ] = U [2 * 4 + 2 ];
516
+ }
517
+ else if (link -> axis == 3 )
518
+ {
519
+ J [0 * n + j ] = U [0 * 4 + 0 ];
520
+ J [1 * n + j ] = U [0 * 4 + 1 ];
521
+ J [2 * n + j ] = U [0 * 4 + 2 ];
522
+ J [3 * n + j ] = 0.0 ;
523
+ J [4 * n + j ] = 0.0 ;
524
+ J [5 * n + j ] = 0.0 ;
525
+ }
526
+ else if (link -> axis == 4 )
527
+ {
528
+ J [0 * n + j ] = U [1 * 4 + 0 ];
529
+ J [1 * n + j ] = U [1 * 4 + 1 ];
530
+ J [2 * n + j ] = U [1 * 4 + 2 ];
531
+ J [3 * n + j ] = 0.0 ;
532
+ J [4 * n + j ] = 0.0 ;
533
+ J [5 * n + j ] = 0.0 ;
534
+ }
535
+ else if (link -> axis == 5 )
536
+ {
537
+ J [0 * n + j ] = U [2 * 4 + 0 ];
538
+ J [1 * n + j ] = U [2 * 4 + 1 ];
539
+ J [2 * n + j ] = U [2 * 4 + 2 ];
540
+ J [3 * n + j ] = 0.0 ;
541
+ J [4 * n + j ] = 0.0 ;
542
+ J [5 * n + j ] = 0.0 ;
543
+ }
544
+
545
+ A (link , ret , q [link -> jindex ]);
546
+ mult (ret , U , temp );
547
+ copy (temp , U );
548
+ j -- ;
549
+ }
550
+ else
551
+ {
552
+ A (link , ret , q [link -> jindex ]);
553
+ mult (ret , U , temp );
554
+ copy (temp , U );
555
+ }
556
+ }
557
+ PyList_Reverse (links );
558
+ }
559
+
438
560
void _jacob0 (PyObject * links , int m , int n , npy_float64 * q , npy_float64 * etool , npy_float64 * tool , npy_float64 * J )
439
561
{
440
562
Link * link ;
@@ -571,12 +693,11 @@ void _fkine(PyObject *links, int n, npy_float64 *q, npy_float64 *etool, npy_floa
571
693
572
694
void A (Link * link , npy_float64 * ret , double eta )
573
695
{
574
- npy_float64 * A , * v ;
575
- A = (npy_float64 * )PyArray_DATA (link -> A );
696
+ npy_float64 * v ;
576
697
577
698
if (!link -> isjoint )
578
699
{
579
- copy (A , ret );
700
+ copy (link -> A , ret );
580
701
return ;
581
702
}
582
703
@@ -590,7 +711,7 @@ void A(Link *link, npy_float64 *ret, double eta)
590
711
link -> op (v , eta );
591
712
592
713
// Multiply ret = A * v
593
- mult (A , v , ret );
714
+ mult (link -> A , v , ret );
594
715
}
595
716
596
717
void copy (npy_float64 * A , npy_float64 * B )
0 commit comments