RoboDK Plug-In Interface
robodktypes.cpp
1#include "robodktypes.h"
2#include <QtMath>
3#include <QDebug>
4
5
6
7//----------------------------------- tJoints class ------------------------
8tJoints::tJoints(int ndofs){
9 _nDOFs = qMin(ndofs, RDK_SIZE_JOINTS_MAX);
10 for (int i=0; i<_nDOFs; i++){
11 _Values[i] = 0.0;
12 }
13}
15 SetValues(copy._Values, copy._nDOFs);
16}
17tJoints::tJoints(const double *joints, int ndofs){
18 SetValues(joints, ndofs);
19}
20tJoints::tJoints(const float *joints, int ndofs){
21 int ndofs_ok = qMin(ndofs, RDK_SIZE_JOINTS_MAX);
22 double jnts[RDK_SIZE_JOINTS_MAX];
23 for (int i=0; i<ndofs_ok; i++){
24 jnts[i] = joints[i];
25 }
26 SetValues(jnts, ndofs_ok);
27}
28tJoints::tJoints(const tMatrix2D *mat2d, int column, int ndofs){
29 if (Matrix2D_Size(mat2d, 2) >= column){
30 _nDOFs = 0;
31 qDebug()<<"Warning: tMatrix2D column outside range when creating joints";
32 }
33 if (ndofs < 0){
34 ndofs = Matrix2D_Size(mat2d, 1);
35 }
36 _nDOFs = qMin(ndofs, RDK_SIZE_JOINTS_MAX);
37
38 double *ptr = Matrix2D_Get_col(mat2d, column);
39 SetValues(ptr, _nDOFs);
40}
41tJoints::tJoints(const QString &str){
42 _nDOFs = 0;
43 FromString(str);
44}
45
46const double* tJoints::ValuesD() const{
47 return _Values;
48}
49const float* tJoints::ValuesF() const{
50 for (int i=0; i<RDK_SIZE_JOINTS_MAX; i++){
51 ((float*)_ValuesF)[i] = _Values[i];
52 }
53 return _ValuesF;
54}
55#ifdef ROBODK_API_FLOATS
56const float* tJoints::Values() const{
57 return ValuesF();
58}
59#else
60const double* tJoints::Values() const{
61 return _Values;
62}
63#endif
64
65double tJoints::Compare(const tJoints &other) const {
66 double sum_diff = 0.0;
67 for (int i=0;i<qMin(_nDOFs, other.Length()); i++){
68 sum_diff += qAbs(_Values[i] - other.Values()[i]);
69 }
70 return sum_diff;
71}
72
73double* tJoints::Data(){
74 return _Values;
75}
76
77
78void tJoints::SetValues(const double *values, int ndofs){
79 if (ndofs >= 0){
80 _nDOFs = qMin(ndofs, RDK_SIZE_JOINTS_MAX);
81 }
82 for (int i=0; i<_nDOFs; i++){
83 _Values[i] = values[i];
84 }
85}
86
87void tJoints::SetValues(const float *values, int ndofs){
88 if (ndofs >= 0){
89 _nDOFs = qMin(ndofs, RDK_SIZE_JOINTS_MAX);
90 }
91 for (int i=0; i<_nDOFs; i++){
92 _Values[i] = values[i];
93 }
94}
95int tJoints::GetValues(double *values){
96 for (int i=0; i<_nDOFs; i++){
97 values[i] = _Values[i];
98 }
99 return _nDOFs;
100}
101QString tJoints::ToString(const QString &separator, int precision) const {
102 QString values;
103 if (_nDOFs <= 0){
104 return values;
105 }
106 values.append(QString::number(_Values[0],'f',precision));
107 for (int i=1; i<_nDOFs; i++){
108 values.append(separator);
109 values.append(QString::number(_Values[i],'f',precision));
110 }
111 return values;
112}
113bool tJoints::FromString(const QString &str){
114 QStringList jnts_list = QString(str).replace(";",",").replace("\t",",").split(",", QString::SkipEmptyParts);
115 _nDOFs = qMin(jnts_list.length(), RDK_SIZE_JOINTS_MAX);
116 for (int i=0; i<_nDOFs; i++){
117 QString stri(jnts_list.at(i));
118 _Values[i] = stri.trimmed().toDouble();
119 }
120 return true;
121}
122
123int tJoints::Length() const{
124 return _nDOFs;
125}
126void tJoints::setLength(int new_length) {
127 if (new_length >= 0 && new_length < _nDOFs){
128 _nDOFs = new_length;
129 }
130}
132 return _nDOFs > 0;
133}
134//---------------------------------------------------------------------
135
136
137
138
139
140//----------------------------------- Mat class ------------------------
141
142Mat transl(double x, double y, double z){
143 return Mat::transl(x,y,z);
144}
145
146Mat rotx(double rx){
147 return Mat::rotx(rx);
148}
149
150Mat roty(double ry){
151 return Mat::roty(ry);
152}
153
154Mat rotz(double rz){
155 return Mat::rotz(rz);
156}
157
158Mat::Mat() : QMatrix4x4() {
159 _valid = true;
160 setToIdentity();
161}
162Mat::Mat(bool valid) : QMatrix4x4() {
163 _valid = valid;
164 setToIdentity();
165}
166
167Mat::Mat(const QMatrix4x4 &matrix) : QMatrix4x4(matrix) {
168 // just copy
169 _valid = true;
170}
171Mat::Mat(const Mat &matrix) : QMatrix4x4(matrix) {
172 // just copy
173 _valid = matrix._valid;
174}
175
176Mat::Mat(double nx, double ox, double ax, double tx, double ny, double oy, double ay, double ty, double nz, double oz, double az, double tz) :
177 QMatrix4x4(nx, ox, ax, tx, ny, oy, ay, ty, nz, oz, az, tz, 0,0,0,1)
178{
179 _valid = true;
180}
181Mat::Mat(const double v[16]) :
182 QMatrix4x4(v[0], v[4], v[8], v[12], v[1], v[5], v[9], v[13], v[2], v[6], v[10], v[14], v[3], v[7], v[11], v[15])
183{
184 _valid = true;
185}
186Mat::Mat(const float v[16]) :
187 QMatrix4x4(v[0], v[4], v[8], v[12], v[1], v[5], v[9], v[13], v[2], v[6], v[10], v[14], v[3], v[7], v[11], v[15])
188{
189 _valid = true;
190}
191
192Mat::Mat(double x, double y, double z):
193 QMatrix4x4(1.0, 0.0, 0.0, x, 0.0, 1.0, 0.0, y, 0.0, 0.0, 1.0, z, 0.0,0.0,0.0,1.0)
194{
195 _valid = true;
196}
197
198
199Mat::~Mat(){
200
201}
202
203void Mat::VX(tXYZ xyz) const{
204 xyz[0] = Get(0, 0);
205 xyz[1] = Get(1, 0);
206 xyz[2] = Get(2, 0);
207}
208void Mat::VY(tXYZ xyz) const{
209 xyz[0] = Get(0, 1);
210 xyz[1] = Get(1, 1);
211 xyz[2] = Get(2, 1);
212}
213void Mat::VZ(tXYZ xyz) const{
214 xyz[0] = Get(0, 2);
215 xyz[1] = Get(1, 2);
216 xyz[2] = Get(2, 2);
217}
218void Mat::Pos(tXYZ xyz) const{
219 xyz[0] = Get(0, 3);
220 xyz[1] = Get(1, 3);
221 xyz[2] = Get(2, 3);
222}
223
224void Mat::setVX(double x, double y, double z){
225 Set(0,0, x);
226 Set(1,0, y);
227 Set(2,0, z);
228}
229void Mat::setVY(double x, double y, double z){
230 Set(0,1, x);
231 Set(1,1, y);
232 Set(2,1, z);
233}
234void Mat::setVZ(double x, double y, double z){
235 Set(0,2, x);
236 Set(1,2, y);
237 Set(2,2, z);
238}
239void Mat::setPos(double x, double y, double z){
240 Set(0,3, x);
241 Set(1,3, y);
242 Set(2,3, z);
243}
244
245void Mat::setVX(double xyz[3]){
246 Set(0,0, xyz[0]);
247 Set(1,0, xyz[1]);
248 Set(2,0, xyz[2]);
249}
250void Mat::setVY(double xyz[3]){
251 Set(0,1, xyz[0]);
252 Set(1,1, xyz[1]);
253 Set(2,1, xyz[2]);
254}
255void Mat::setVZ(double xyz[3]){
256 Set(0,2, xyz[0]);
257 Set(1,2, xyz[1]);
258 Set(2,2, xyz[2]);
259}
260void Mat::setPos(double xyz[3]){
261 Set(0,3, xyz[0]);
262 Set(1,3, xyz[1]);
263 Set(2,3, xyz[2]);
264}
265
266
267void Mat::setValues(double pose[16]){
268 Set(0,0, pose[0]);
269 Set(1,0, pose[1]);
270 Set(2,0, pose[2]);
271 Set(3,0, pose[3]);
272
273 Set(0,1, pose[4]);
274 Set(1,1, pose[5]);
275 Set(2,1, pose[6]);
276 Set(3,1, pose[7]);
277
278 Set(0,2, pose[8]);
279 Set(1,2, pose[9]);
280 Set(2,2, pose[10]);
281 Set(3,2, pose[11]);
282
283 Set(0,3, pose[12]);
284 Set(1,3, pose[13]);
285 Set(2,3, pose[14]);
286 Set(3,3, pose[15]);
287}
288
289
290void Mat::Set(int i, int j, double value){
291 QVector4D rw(this->row(i));
292 rw[j] = value;
293 setRow(i, rw);
294 // the following should not crash!!
295 //float **dt_ok = (float**) data();
296 //dt_ok[i][j] = value;
297}
298
299double Mat::Get(int i, int j) const{
300 return row(i)[j];
301 // the following hsould be allowed!!
302 //return ((const float**)data())[i][j];
303}
304
305Mat Mat::inv() const{
306 return this->inverted();
307}
308
309
310bool Mat::isHomogeneous() const {
311 const bool debug_info = false;
312 tXYZ vx, vy, vz;
313 const double tol = 1e-7;
314 VX(vx);
315 VY(vy);
316 VZ(vz);
317 if (fabs((double) DOT(vx,vy)) > tol){
318 if (debug_info){
319 qDebug() << "Vector X and Y are not perpendicular!";
320 }
321 return false;
322 } else if (fabs((double) DOT(vx,vz)) > tol){
323 if (debug_info){
324 qDebug() << "Vector X and Z are not perpendicular!";
325 }
326 return false;
327 } else if (fabs((double) DOT(vy,vz)) > tol){
328 if (debug_info){
329 qDebug() << "Vector Y and Z are not perpendicular!";
330 }
331 return false;
332 } else if (fabs((double) (NORM(vx)-1.0)) > tol){
333 if (debug_info){
334 qDebug() << "Vector X is not unitary! " << NORM(vx);
335 }
336 return false;
337 } else if (fabs((double) (NORM(vy)-1.0)) > tol){
338 if (debug_info){
339 qDebug() << "Vector Y is not unitary! " << NORM(vy);
340 }
341 return false;
342 } else if (fabs((double) (NORM(vz)-1.0)) > tol){
343 if (debug_info){
344 qDebug() << "Vector Z is not unitary! " << NORM(vz);
345 }
346 return false;
347 }
348 return true;
349}
350
352 tXYZ vx, vy, vz;
353 VX(vx);
354 VY(vy);
355 VZ(vz);
356 bool is_homogeneous = isHomogeneous();
357 //if (is_homogeneous){
358 // return false;
359 //}
360
361 NORMALIZE(vx);
362 CROSS(vz, vx, vy);
363 NORMALIZE(vz);
364 CROSS(vy, vz, vx);
365 NORMALIZE(vy);
366 setVX(vx);
367 setVY(vy);
368 setVZ(vz);
369 Set(3,0, 0.0);
370 Set(3,1, 0.0);
371 Set(3,2, 0.0);
372 Set(3,3, 1.0);
373 return !is_homogeneous;
374}
375
376
377
378//----------------------------------------------------
379
380void Mat::ToXYZRPW(tXYZWPR xyzwpr) const{
381 double x = Get(0,3);
382 double y = Get(1,3);
383 double z = Get(2,3);
384 double w, p, r;
385 if (Get(2,0) > (1.0 - 1e-6)){
386 p = -M_PI*0.5;
387 r = 0;
388 w = atan2(-Get(1,2), Get(1,1));
389 } else if (Get(2,0) < -1.0 + 1e-6){
390 p = 0.5*M_PI;
391 r = 0;
392 w = atan2(Get(1,2),Get(1,1));
393 } else {
394 p = atan2(-Get(2, 0), sqrt(Get(0, 0) * Get(0, 0) + Get(1, 0) * Get(1, 0)));
395 w = atan2(Get(1, 0), Get(0, 0));
396 r = atan2(Get(2, 1), Get(2, 2));
397 }
398 xyzwpr[0] = x;
399 xyzwpr[1] = y;
400 xyzwpr[2] = z;
401 xyzwpr[3] = r*180.0/M_PI;
402 xyzwpr[4] = p*180.0/M_PI;
403 xyzwpr[5] = w*180.0/M_PI;
404}
405QString Mat::ToString(const QString &separator, int precision, bool xyzwpr_only) const {
406 if (!Valid()){
407 return "Mat(Invalid)";
408 }
409 QString str;
410 if (!isHomogeneous()){
411 str.append("Warning!! Pose is not homogeneous! Use Mat::MakeHomogeneous() to make this matrix homogeneous\n");
412 }
413 str.append("Mat(XYZRPW_2_Mat(");
414
415 tXYZWPR xyzwpr;
416 ToXYZRPW(xyzwpr);
417 str.append(QString::number(xyzwpr[0],'f',precision));
418 for (int i=1; i<6; i++){
419 str.append(separator);
420 str.append(QString::number(xyzwpr[i],'f',precision));
421 }
422 str.append("))");
423
424 if (xyzwpr_only){
425 return str;
426 }
427 str.append("\n");
428 for (int i=0; i<4; i++){
429 str.append("[");
430 for (int j=0; j<4; j++){
431 str.append(QString::number(row(i)[j], 'f', precision));
432 if (j < 3){
433 str.append(separator);
434 }
435 }
436 str.append("];\n");
437 }
438 return str;
439}
440bool Mat::FromString(const QString &pose_str){
441 QStringList values_list = QString(pose_str).replace(";",",").replace("\t",",").split(",", QString::SkipEmptyParts);
442 int nvalues = qMin(values_list.length(), 6);
443 tXYZWPR xyzwpr;
444 for (int i=0; i<6; i++){
445 xyzwpr[i] = 0.0;
446 }
447 if (nvalues < 6){
448 FromXYZRPW(xyzwpr);
449 return false;
450 }
451 for (int i=0; i<nvalues; i++){
452 QString stri(values_list.at(i));
453 xyzwpr[i] = stri.trimmed().toDouble();
454 }
455 FromXYZRPW(xyzwpr);
456 return true;
457}
458
459Mat Mat::XYZRPW_2_Mat(double x, double y, double z, double r, double p, double w){
460 double a = r * M_PI / 180.0;
461 double b = p * M_PI / 180.0;
462 double c = w * M_PI / 180.0;
463 double ca = cos(a);
464 double sa = sin(a);
465 double cb = cos(b);
466 double sb = sin(b);
467 double cc = cos(c);
468 double sc = sin(c);
469 return Mat(cb * cc, cc * sa * sb - ca * sc, sa * sc + ca * cc * sb, x, cb * sc, ca * cc + sa * sb * sc, ca * sb * sc - cc * sa, y, -sb, cb * sa, ca * cb, z);
470}
471Mat Mat::XYZRPW_2_Mat(tXYZWPR xyzwpr){
472 return XYZRPW_2_Mat(xyzwpr[0], xyzwpr[1], xyzwpr[2], xyzwpr[3], xyzwpr[4], xyzwpr[5]);
473}
474
475void Mat::FromXYZRPW(tXYZWPR xyzwpr){
476 Mat newmat = Mat::XYZRPW_2_Mat(xyzwpr[0], xyzwpr[1], xyzwpr[2], xyzwpr[3], xyzwpr[4], xyzwpr[5]);
477 for (int i=0; i<4; i++){
478 for (int j=0; j<4; j++){
479 this->Set(i,j, newmat.Get(i,j));
480 }
481 }
482}
483
484const double* Mat::ValuesD() const {
485 double* _ddata16_non_const = (double*) _ddata16;
486 for(int i=0; i<16; ++i){
487 _ddata16_non_const[i] = constData()[i];
488 }
489 return _ddata16;
490}
491const float* Mat::ValuesF() const {
492 return constData();
493}
494
495#ifdef ROBODK_API_FLOATS
496const float* Mat::Values() const {
497 return constData();
498}
499#else
500const double* Mat::Values() const {
501 return ValuesD();
502}
503
504#endif
505
506
507
508void Mat::Values(double data[16]) const{
509 for(int i=0; i<16; ++i){
510 data[i] = constData()[i];
511 }
512}
513void Mat::Values(float data[16]) const{
514 for(int i=0; i<16; ++i){
515 data[i] = constData()[i];
516 }
517}
518bool Mat::Valid() const{
519 return _valid;
520}
521
522Mat Mat::transl(double x, double y, double z){
523 Mat mat;
524 mat.setToIdentity();
525 mat.setPos(x, y, z);
526 return mat;
527}
528
529Mat Mat::rotx(double rx){
530 double cx = cos(rx);
531 double sx = sin(rx);
532 return Mat(1, 0, 0, 0, 0, cx, -sx, 0, 0, sx, cx, 0);
533}
534
535Mat Mat::roty(double ry){
536 double cy = cos(ry);
537 double sy = sin(ry);
538 return Mat(cy, 0, sy, 0, 0, 1, 0, 0, -sy, 0, cy, 0);
539}
540
541Mat Mat::rotz(double rz){
542 double cz = cos(rz);
543 double sz = sin(rz);
544 return Mat(cz, -sz, 0, 0, sz, cz, 0, 0, 0, 0, 1, 0);
545}
546
547
548
549
550
551
552
553//---------------------------------------------------------------------------------------------------
554//---------------------------------------------------------------------------------------------------
555//---------------------------------------------------------------------------------------------------
556//---------------------------------------------------------------------------------------------------
557//---------------------------------------------------------------------------------------------------
558//---------------------------------------------------------------------------------------------------
560// 2D matrix functions
562void emxInit_real_T(tMatrix2D **pEmxArray, int numDimensions){
563 tMatrix2D *emxArray;
564 int i;
565 *pEmxArray = (tMatrix2D *)malloc(sizeof(tMatrix2D));
566 emxArray = *pEmxArray;
567 emxArray->data = (double *)NULL;
568 emxArray->numDimensions = numDimensions;
569 emxArray->size = (int *)malloc((unsigned int)(sizeof(int) * numDimensions));
570 emxArray->allocatedSize = 0;
571 emxArray->canFreeData = true;
572 for (i = 0; i < numDimensions; i++) {
573 emxArray->size[i] = 0;
574 }
575}
577tMatrix2D* Matrix2D_Create() {
578 tMatrix2D *matrix;
579 emxInit_real_T((tMatrix2D**)(&matrix), 2);
580 return matrix;
581}
582
583
584void emxFree_real_T(tMatrix2D **pEmxArray){
585 if (*pEmxArray != (tMatrix2D *)NULL) {
586 if (((*pEmxArray)->data != (double *)NULL) && (*pEmxArray)->canFreeData) {
587 free((void *)(*pEmxArray)->data);
588 }
589 free((void *)(*pEmxArray)->size);
590 free((void *)*pEmxArray);
591 *pEmxArray = (tMatrix2D *)NULL;
592 }
593}
594
595void Matrix2D_Delete(tMatrix2D **mat) {
596 emxFree_real_T((tMatrix2D**)(mat));
597}
598
599
600
601void emxEnsureCapacity(tMatrix2D *emxArray, int oldNumel, unsigned int elementSize){
602 int newNumel;
603 int i;
604 double *newData;
605 if (oldNumel < 0) {
606 oldNumel = 0;
607 }
608 newNumel = 1;
609 for (i = 0; i < emxArray->numDimensions; i++) {
610 newNumel *= emxArray->size[i];
611 }
612 if (newNumel > emxArray->allocatedSize) {
613 i = emxArray->allocatedSize;
614 if (i < 16) {
615 i = 16;
616 }
617 while (i < newNumel) {
618 if (i > 1073741823) {
619 i =(2147483647);//MAX_int32_T;
620 } else {
621 i <<= 1;
622 }
623 }
624 newData = (double*) calloc((unsigned int)i, elementSize);
625 if (emxArray->data != NULL) {
626 memcpy(newData, emxArray->data, elementSize * oldNumel);
627 if (emxArray->canFreeData) {
628 free(emxArray->data);
629 }
630 }
631 emxArray->data = newData;
632 emxArray->allocatedSize = i;
633 emxArray->canFreeData = true;
634 }
635}
636
637void Matrix2D_Set_Size(tMatrix2D *mat, int rows, int cols) {
638 int old_numel;
639 int numbel;
640 old_numel = mat->size[0] * mat->size[1];
641 mat->size[0] = rows;
642 mat->size[1] = cols;
643 numbel = rows*cols;
644 emxEnsureCapacity(mat, old_numel, sizeof(double));
645 /*for (i=0; i<numbel; i++){
646 mat->data[i] = 0.0;
647 }*/
648}
649
650int Matrix2D_Size(const tMatrix2D *var, int dim) { // ONE BASED!!
651 if (var->numDimensions >= dim) {
652 return var->size[dim - 1];
653 }
654 else {
655 return 0;
656 }
657}
658int Matrix2D_Get_ncols(const tMatrix2D *var) {
659 return Matrix2D_Size(var, 2);
660}
661int Matrix2D_Get_nrows(const tMatrix2D *var) {
662 return Matrix2D_Size(var, 1);
663}
664double Matrix2D_Get_ij(const tMatrix2D *var, int i, int j) { // ZERO BASED!!
665 return var->data[var->size[0] * j + i];
666}
667void Matrix2D_Set_ij(const tMatrix2D *var, int i, int j, double value) { // ZERO BASED!!
668 var->data[var->size[0] * j + i] = value;
669}
670
671double *Matrix2D_Get_col(const tMatrix2D *var, int col) { // ZERO BASED!!
672 return (var->data + var->size[0] * col);
673}
674bool Matrix2D_Copy(const tMatrix2D *from, tMatrix2D *to){
675 if (from->numDimensions != 2 || to->numDimensions != 2){
676 Matrix2D_Set_Size(to, 0,0);
677 return false;
678 }
679 int sz1 = Matrix2D_Size(from,1);
680 int sz2 = Matrix2D_Size(from,2);
681 Matrix2D_Set_Size(to, sz1, sz2);
682 int numel = sz1*sz2;
683 for (int i=0; i<numel; i++){
684 to->data[i] = from->data[i];
685 }
686 //to->canFreeData = from->canFreeData;
687 return true;
688}
689
690
691void Matrix2D_Add(tMatrix2D *var, const double *array, int numel){
692 int oldnumel;
693 int size1 = var->size[0];
694 int size2 = var->size[1];
695 oldnumel = size1*size2;
696 var->size[1] = size2 + 1;
697 emxEnsureCapacity(var, oldnumel, (int)sizeof(double));
698 numel = qMin(numel, size1);
699 for (int i=0; i<numel; i++){
700 var->data[size1*size2 + i] = array[i];
701 }
702}
703
704void Matrix2D_Add(tMatrix2D *var, const tMatrix2D *varadd){
705 int oldnumel;
706 int size1 = var->size[0];
707 int size2 = var->size[1];
708 int size1_ap = varadd->size[0];
709 int size2_ap = varadd->size[1];
710 int numel = size1_ap*size2_ap;
711 if (size1 != size1_ap){
712 return;
713 }
714 oldnumel = size1*size2;
715 var->size[1] = size2 + size2_ap;
716 emxEnsureCapacity(var, oldnumel, (int)sizeof(double));
717 for (int i=0; i<numel; i++){
718 var->data[size1*size2 + i] = varadd->data[i];
719 }
720}
721
722void Debug_Array(const double *array, int arraysize) {
723 int i;
724 QString strout;
725 for (i = 0; i < arraysize; i++) {
726 strout.append(QString::number(array[i], 'f', 3));
727 if (i < arraysize - 1) {
728 strout.append(" , ");
729 }
730 }
731 qDebug().noquote() << strout;
732}
733
734void Debug_Matrix2D(const tMatrix2D *emx) {
735 int size1;
736 int size2;
737 int j;
738 double *column;
739 size1 = Matrix2D_Get_nrows(emx);
740 size2 = Matrix2D_Get_ncols(emx);
741 qDebug().noquote() << "Matrix size = " << size1 << " x " << size2;
742 if (size1*size2 == 0){ return; }
743 for (j = 0; j<size2; j++) {
744 column = Matrix2D_Get_col(emx, j);
745 Debug_Array(column, size1);
746 }
747}
748
749void Matrix2D_Save(QDataStream *st, tMatrix2D *emx){
750 int i;
751 *st << emx->numDimensions;
752 int size_values = 1;
753 for (i=0; i< emx->numDimensions; i++){
754 qint32 sizei = emx->size[i];
755 size_values = size_values * sizei;
756 *st << sizei;
757 }
758 for (i=0; i<size_values; i++){
759 *st << emx->data[i];
760 }
761}
762void Matrix2D_Save(QTextStream *st, tMatrix2D *emx, bool csv){
763 int size1;
764 int size2;
765 int j;
766 double *column;
767 size1 = Matrix2D_Get_nrows(emx);
768 size2 = Matrix2D_Get_ncols(emx);
769 //*st << "% Matrix size = " << size1 << " x " << size2;
770 if (size1*size2 == 0){ return; }
771 if (csv){
772 for (j = 0; j<size2; j++) {
773 column = Matrix2D_Get_col(emx, j);
774 for (int i = 0; i < size1; i++) {
775 *st << QString::number(column[i], 'f', 8) << ", ";
776 }
777 *st << "\n";
778 }
779 } else {
780 for (j = 0; j<size2; j++) {
781 column = Matrix2D_Get_col(emx, j);
782 *st << "[";
783 for (int i = 0; i < size1; i++) {
784 *st << QString::number(column[i], 'f', 8) << " ";
785 }
786 *st << "];\n";
787 }
788 }
789}
790
791void Matrix2D_Load(QDataStream *st, tMatrix2D **emx){
792 if (st->atEnd()){
793 qDebug() << "No data to read";
794 return;
795 }
796 if (*emx != nullptr){
797 Matrix2D_Delete(emx);
798 }
799 int i;
800 qint32 ndim;
801 qint32 sizei;
802 *st >> ndim;
803 qDebug() << "Loading matrix of dimensions: " << ndim;
804 emxInit_real_T(emx, ndim);
805 int size_values = 1;
806 for (i=0; i<ndim; i++){
807 *st >> sizei;
808 size_values = size_values * sizei;
809 (*emx)->size[i] = sizei;
810 }
811 //emxEnsureCapacity((emxArray__common *) *emx, 0, (int32_T)sizeof(real_T));
812 emxEnsureCapacity(*emx, 0, sizeof(double));
813 double value;
814 for (i=0; i<size_values; i++){
815 *st >> value;
816 (*emx)->data[i] = value;
817 }
818}
819
820
821/*
822void Debug_Mat(Mat pose, char show_full_pose) {
823 tMatrix4x4 pose_tr;
824 double xyzwpr[6];
825 int j;
826 if (show_full_pose > 0) {
827 POSE_TR(pose_tr, pose);
828 printf("Pose size = [4x4]\n");
829 //std::cout << "Pose size = [4x4]\n";
830 for (j = 0; j < 4; j++) {
831 Debug_Array(pose_tr + j * 4, 4);
832 printf("\n");
833 //std::cout << "\n";
834 }
835 }
836 else {
837 POSE_2_XYZWPR(xyzwpr, pose);
838 //std::cout << "XYZWPR = [ ";
839 printf("XYZWPR = [ ");
840 Debug_Array(xyzwpr, 6);
841 printf(" ]\n");
842 //std::cout << " ]\n";
843 }
844}
845*/
846
The Mat class represents a 4x4 pose matrix. The main purpose of this object is to represent a pose in...
Definition: robodktypes.h:361
QString ToString(const QString &separator=", ", int precision=3, bool xyzrpw_only=false) const
Retrieve a string representation of the pose.
Mat()
Create the identity matrix.
void VX(tXYZ xyz) const
Get the X vector (N vector)
void setVX(double x, double y, double z)
Set the X vector values (N vector)
void FromXYZRPW(tXYZWPR xyzwpr)
Calculates the pose from the position and euler angles ([x,y,z,r,p,w] vector) The result is the same ...
void VY(tXYZ xyz) const
Get the Y vector (O vector)
static Mat transl(double x, double y, double z)
Return a translation matrix.
void ToXYZRPW(tXYZWPR xyzwpr) const
Calculates the equivalent position and euler angles ([x,y,z,r,p,w] vector) of the given pose Note: tr...
void setVZ(double x, double y, double z)
Set the Z vector values (A vector)
double Get(int r, int c) const
Get a matrix value.
bool Valid() const
Check if the matrix is valid.
void setVY(double x, double y, double z)
Set the Y vector values (O vector)
static Mat roty(double ry)
Return a Y-axis rotation matrix
const double * Values() const
Get a pointer to the 16-digit array (doubles or floats if ROBODK_API_FLOATS is defined).
void setValues(double pose[16])
Set the pose values.
void Pos(tXYZ xyz) const
Get the position (T position), in mm.
bool MakeHomogeneous()
Forces 4x4 matrix to be homogeneous (vx,vy,vz must be unitary vectors and respect: vx x vy = vz)....
static Mat rotz(double rz)
Return a Z-axis rotation matrix.
const double * ValuesD() const
Get a pointer to the 16-digit double array.
double _ddata16[16]
Copy of the data as a double array.
Definition: robodktypes.h:622
bool FromString(const QString &str)
Set the matrix given a XYZRPW string array (6-values)
double _valid
Flags if a matrix is not valid.
Definition: robodktypes.h:617
Mat inv() const
Invert the pose (homogeneous matrix assumed)
void setPos(double x, double y, double z)
Set the position (T position) in mm.
void VZ(tXYZ xyz) const
Get the Z vector (A vector)
bool isHomogeneous() const
Returns true if the matrix is homogeneous, otherwise it returns false.
const float * ValuesF() const
Get a pointer to the 16-digit array as an array of floats.
void Set(int r, int c, double value)
Set a matrix value.
static Mat rotx(double rx)
Return the X-axis rotation matrix.
static Mat XYZRPW_2_Mat(double x, double y, double z, double r, double p, double w)
Calculates the pose from the position and euler angles ([x,y,z,r,p,w] vector) The result is the same ...
The tJoints class represents a joint position of a robot (robot axes).
Definition: robodktypes.h:239
int GetValues(double *joints)
GetValues.
Definition: robodktypes.cpp:95
tJoints(int ndofs=0)
tJoints
Definition: robodktypes.cpp:8
QString ToString(const QString &separator=", ", int precision=3) const
Retrieve a string representation of the joint values.
int Length() const
Number of joint axes of the robot (or degrees of freedom)
const double * Values() const
Joint values.
Definition: robodktypes.cpp:60
bool Valid()
Check if the joints are valid. For example, when we request the Inverse kinematics and there is no so...
int _nDOFs
number of degrees of freedom
Definition: robodktypes.h:340
double * Data()
Definition: robodktypes.cpp:73
const double * ValuesD() const
Joint values.
Definition: robodktypes.cpp:46
double _Values[RDK_SIZE_JOINTS_MAX]
joint values (doubles, used to store the joint values)
Definition: robodktypes.h:343
bool FromString(const QString &str)
Set the joint values given a comma-separated string. Tabs and spaces are also allowed.
void setLength(int new_length)
Set the length of the array (only shrinking the array is allowed)
float _ValuesF[RDK_SIZE_JOINTS_MAX]
joint values (floats, used to return a copy as a float pointer)
Definition: robodktypes.h:346
const float * ValuesF() const
Joint values.
Definition: robodktypes.cpp:49
void SetValues(const double *joints, int ndofs=-1)
Set the joint values in deg or mm. You can also important provide the number of degrees of freedom (6...
Definition: robodktypes.cpp:78
The tMatrix2D struct represents a variable size 2d Matrix. Use the Matrix2D_... functions to oeprate ...
Definition: robodktypes.h:145
double * data
Pointer to the data.
Definition: robodktypes.h:147
int * size
Pointer to the size array.
Definition: robodktypes.h:150
int allocatedSize
Allocated size.
Definition: robodktypes.h:153
int numDimensions
Number of dimensions (usually 2)
Definition: robodktypes.h:156