RoboDK Plug-In Interface
Loading...
Searching...
No Matches
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(",", Qt::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 QString pose_str2(pose_str.trimmed());
442 if (pose_str2.startsWith("Mat(",Qt::CaseInsensitive)){
443 pose_str2.remove(0, 4).trimmed();
444 }
445 if (pose_str2.startsWith("XYZRPW_2_Mat(",Qt::CaseInsensitive)){
446 pose_str2.remove(0, 13).trimmed();
447 }
448 if (pose_str2.endsWith("))")){
449 pose_str2.chop(2);
450 }
451
452 QStringList values_list = pose_str2.replace(";",",").replace("\t",",").split(",", Qt::SkipEmptyParts);
453 tXYZWPR xyzwpr = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
454 if (values_list.length() < 6){
455 FromXYZRPW(xyzwpr);
456 return false;
457 }
458 for (int i=0; i<6; i++){
459 QString stri(values_list.at(i));
460 xyzwpr[i] = stri.trimmed().toDouble();
461 }
462 FromXYZRPW(xyzwpr);
463 return true;
464}
465
466Mat Mat::XYZRPW_2_Mat(double x, double y, double z, double r, double p, double w){
467 double a = r * M_PI / 180.0;
468 double b = p * M_PI / 180.0;
469 double c = w * M_PI / 180.0;
470 double ca = cos(a);
471 double sa = sin(a);
472 double cb = cos(b);
473 double sb = sin(b);
474 double cc = cos(c);
475 double sc = sin(c);
476 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);
477}
478Mat Mat::XYZRPW_2_Mat(tXYZWPR xyzwpr){
479 return XYZRPW_2_Mat(xyzwpr[0], xyzwpr[1], xyzwpr[2], xyzwpr[3], xyzwpr[4], xyzwpr[5]);
480}
481
482void Mat::FromXYZRPW(tXYZWPR xyzwpr){
483 Mat newmat = Mat::XYZRPW_2_Mat(xyzwpr[0], xyzwpr[1], xyzwpr[2], xyzwpr[3], xyzwpr[4], xyzwpr[5]);
484 for (int i=0; i<4; i++){
485 for (int j=0; j<4; j++){
486 this->Set(i,j, newmat.Get(i,j));
487 }
488 }
489}
490
491const double* Mat::ValuesD() const {
492 double* _ddata16_non_const = (double*) _ddata16;
493 for(int i=0; i<16; ++i){
494 _ddata16_non_const[i] = constData()[i];
495 }
496 return _ddata16;
497}
498const float* Mat::ValuesF() const {
499 return constData();
500}
501
502#ifdef ROBODK_API_FLOATS
503const float* Mat::Values() const {
504 return constData();
505}
506#else
507const double* Mat::Values() const {
508 return ValuesD();
509}
510
511#endif
512
513
514
515void Mat::Values(double data[16]) const{
516 for(int i=0; i<16; ++i){
517 data[i] = constData()[i];
518 }
519}
520void Mat::Values(float data[16]) const{
521 for(int i=0; i<16; ++i){
522 data[i] = constData()[i];
523 }
524}
525bool Mat::Valid() const{
526 return _valid;
527}
528
529Mat Mat::transl(double x, double y, double z){
530 Mat mat;
531 mat.setToIdentity();
532 mat.setPos(x, y, z);
533 return mat;
534}
535
536Mat Mat::rotx(double rx){
537 double cx = cos(rx);
538 double sx = sin(rx);
539 return Mat(1, 0, 0, 0, 0, cx, -sx, 0, 0, sx, cx, 0);
540}
541
542Mat Mat::roty(double ry){
543 double cy = cos(ry);
544 double sy = sin(ry);
545 return Mat(cy, 0, sy, 0, 0, 1, 0, 0, -sy, 0, cy, 0);
546}
547
548Mat Mat::rotz(double rz){
549 double cz = cos(rz);
550 double sz = sin(rz);
551 return Mat(cz, -sz, 0, 0, sz, cz, 0, 0, 0, 0, 1, 0);
552}
553
554
555
556
557
558
559
560//---------------------------------------------------------------------------------------------------
561//---------------------------------------------------------------------------------------------------
562//---------------------------------------------------------------------------------------------------
563//---------------------------------------------------------------------------------------------------
564//---------------------------------------------------------------------------------------------------
565//---------------------------------------------------------------------------------------------------
567// 2D matrix functions
569void emxInit_real_T(tMatrix2D **pEmxArray, int numDimensions){
570 tMatrix2D *emxArray;
571 int i;
572 *pEmxArray = (tMatrix2D *)malloc(sizeof(tMatrix2D));
573 emxArray = *pEmxArray;
574 emxArray->data = (double *)NULL;
575 emxArray->numDimensions = numDimensions;
576 emxArray->size = (int *)malloc((unsigned int)(sizeof(int) * numDimensions));
577 emxArray->allocatedSize = 0;
578 emxArray->canFreeData = true;
579 for (i = 0; i < numDimensions; i++) {
580 emxArray->size[i] = 0;
581 }
582}
584tMatrix2D* Matrix2D_Create() {
585 tMatrix2D *matrix;
586 emxInit_real_T((tMatrix2D**)(&matrix), 2);
587 return matrix;
588}
589
590
591void emxFree_real_T(tMatrix2D **pEmxArray){
592 if (*pEmxArray != (tMatrix2D *)NULL) {
593 if (((*pEmxArray)->data != (double *)NULL) && (*pEmxArray)->canFreeData) {
594 free((void *)(*pEmxArray)->data);
595 }
596 free((void *)(*pEmxArray)->size);
597 free((void *)*pEmxArray);
598 *pEmxArray = (tMatrix2D *)NULL;
599 }
600}
601
602void Matrix2D_Delete(tMatrix2D **mat) {
603 emxFree_real_T((tMatrix2D**)(mat));
604}
605
606
607
608void emxEnsureCapacity(tMatrix2D *emxArray, int oldNumel, unsigned int elementSize){
609 int newNumel;
610 int i;
611 double *newData;
612 if (oldNumel < 0) {
613 oldNumel = 0;
614 }
615 newNumel = 1;
616 for (i = 0; i < emxArray->numDimensions; i++) {
617 newNumel *= emxArray->size[i];
618 }
619 if (newNumel > emxArray->allocatedSize) {
620 i = emxArray->allocatedSize;
621 if (i < 16) {
622 i = 16;
623 }
624 while (i < newNumel) {
625 if (i > 1073741823) {
626 i =(2147483647);//MAX_int32_T;
627 } else {
628 i <<= 1;
629 }
630 }
631 newData = (double*) calloc((unsigned int)i, elementSize);
632 if (emxArray->data != NULL) {
633 memcpy(newData, emxArray->data, elementSize * oldNumel);
634 if (emxArray->canFreeData) {
635 free(emxArray->data);
636 }
637 }
638 emxArray->data = newData;
639 emxArray->allocatedSize = i;
640 emxArray->canFreeData = true;
641 }
642}
643
644void Matrix2D_Set_Size(tMatrix2D *mat, int rows, int cols) {
645 int old_numel;
646 int numbel;
647 old_numel = mat->size[0] * mat->size[1];
648 mat->size[0] = rows;
649 mat->size[1] = cols;
650 numbel = rows*cols;
651 emxEnsureCapacity(mat, old_numel, sizeof(double));
652 /*for (i=0; i<numbel; i++){
653 mat->data[i] = 0.0;
654 }*/
655}
656
657int Matrix2D_Size(const tMatrix2D *var, int dim) { // ONE BASED!!
658 if (var->numDimensions >= dim) {
659 return var->size[dim - 1];
660 }
661 else {
662 return 0;
663 }
664}
665int Matrix2D_Get_ncols(const tMatrix2D *var) {
666 return Matrix2D_Size(var, 2);
667}
668int Matrix2D_Get_nrows(const tMatrix2D *var) {
669 return Matrix2D_Size(var, 1);
670}
671double Matrix2D_Get_ij(const tMatrix2D *var, int i, int j) { // ZERO BASED!!
672 return var->data[var->size[0] * j + i];
673}
674void Matrix2D_Set_ij(const tMatrix2D *var, int i, int j, double value) { // ZERO BASED!!
675 var->data[var->size[0] * j + i] = value;
676}
677
678double *Matrix2D_Get_col(const tMatrix2D *var, int col) { // ZERO BASED!!
679 return (var->data + var->size[0] * col);
680}
681bool Matrix2D_Copy(const tMatrix2D *from, tMatrix2D *to){
682 if (from->numDimensions != 2 || to->numDimensions != 2){
683 Matrix2D_Set_Size(to, 0,0);
684 return false;
685 }
686 int sz1 = Matrix2D_Size(from,1);
687 int sz2 = Matrix2D_Size(from,2);
688 Matrix2D_Set_Size(to, sz1, sz2);
689 int numel = sz1*sz2;
690 for (int i=0; i<numel; i++){
691 to->data[i] = from->data[i];
692 }
693 //to->canFreeData = from->canFreeData;
694 return true;
695}
696
697
698void Matrix2D_Add(tMatrix2D *var, const double *array, int numel){
699 int oldnumel;
700 int size1 = var->size[0];
701 int size2 = var->size[1];
702 oldnumel = size1*size2;
703 var->size[1] = size2 + 1;
704 emxEnsureCapacity(var, oldnumel, (int)sizeof(double));
705 numel = qMin(numel, size1);
706 for (int i=0; i<numel; i++){
707 var->data[size1*size2 + i] = array[i];
708 }
709}
710
711void Matrix2D_Add(tMatrix2D *var, const tMatrix2D *varadd){
712 int oldnumel;
713 int size1 = var->size[0];
714 int size2 = var->size[1];
715 int size1_ap = varadd->size[0];
716 int size2_ap = varadd->size[1];
717 int numel = size1_ap*size2_ap;
718 if (size1 != size1_ap){
719 return;
720 }
721 oldnumel = size1*size2;
722 var->size[1] = size2 + size2_ap;
723 emxEnsureCapacity(var, oldnumel, (int)sizeof(double));
724 for (int i=0; i<numel; i++){
725 var->data[size1*size2 + i] = varadd->data[i];
726 }
727}
728
729void Debug_Array(const double *array, int arraysize) {
730 int i;
731 QString strout;
732 for (i = 0; i < arraysize; i++) {
733 strout.append(QString::number(array[i], 'f', 3));
734 if (i < arraysize - 1) {
735 strout.append(" , ");
736 }
737 }
738 qDebug().noquote() << strout;
739}
740
741void Debug_Matrix2D(const tMatrix2D *emx) {
742 int size1;
743 int size2;
744 int j;
745 double *column;
746 size1 = Matrix2D_Get_nrows(emx);
747 size2 = Matrix2D_Get_ncols(emx);
748 qDebug().noquote() << "Matrix size = " << size1 << " x " << size2;
749 if (size1*size2 == 0){ return; }
750 for (j = 0; j<size2; j++) {
751 column = Matrix2D_Get_col(emx, j);
752 Debug_Array(column, size1);
753 }
754}
755
756void Matrix2D_Save(QDataStream *st, tMatrix2D *emx){
757 int i;
758 *st << emx->numDimensions;
759 int size_values = 1;
760 for (i=0; i< emx->numDimensions; i++){
761 qint32 sizei = emx->size[i];
762 size_values = size_values * sizei;
763 *st << sizei;
764 }
765 for (i=0; i<size_values; i++){
766 *st << emx->data[i];
767 }
768}
769void Matrix2D_Save(QTextStream *st, tMatrix2D *emx, bool csv){
770 int size1;
771 int size2;
772 int j;
773 double *column;
774 size1 = Matrix2D_Get_nrows(emx);
775 size2 = Matrix2D_Get_ncols(emx);
776 //*st << "% Matrix size = " << size1 << " x " << size2;
777 if (size1*size2 == 0){ return; }
778 if (csv){
779 for (j = 0; j<size2; j++) {
780 column = Matrix2D_Get_col(emx, j);
781 for (int i = 0; i < size1; i++) {
782 *st << QString::number(column[i], 'f', 8) << ", ";
783 }
784 *st << "\n";
785 }
786 } else {
787 for (j = 0; j<size2; j++) {
788 column = Matrix2D_Get_col(emx, j);
789 *st << "[";
790 for (int i = 0; i < size1; i++) {
791 *st << QString::number(column[i], 'f', 8) << " ";
792 }
793 *st << "];\n";
794 }
795 }
796}
797
798void Matrix2D_Load(QDataStream *st, tMatrix2D **emx){
799 if (st->atEnd()){
800 qDebug() << "No data to read";
801 return;
802 }
803 if (*emx != nullptr){
804 Matrix2D_Delete(emx);
805 }
806 int i;
807 qint32 ndim;
808 qint32 sizei;
809 *st >> ndim;
810 qDebug() << "Loading matrix of dimensions: " << ndim;
811 emxInit_real_T(emx, ndim);
812 int size_values = 1;
813 for (i=0; i<ndim; i++){
814 *st >> sizei;
815 size_values = size_values * sizei;
816 (*emx)->size[i] = sizei;
817 }
818 //emxEnsureCapacity((emxArray__common *) *emx, 0, (int32_T)sizeof(real_T));
819 emxEnsureCapacity(*emx, 0, sizeof(double));
820 double value;
821 for (i=0; i<size_values; i++){
822 *st >> value;
823 (*emx)->data[i] = value;
824 }
825}
826
827
828/*
829void Debug_Mat(Mat pose, char show_full_pose) {
830 tMatrix4x4 pose_tr;
831 double xyzwpr[6];
832 int j;
833 if (show_full_pose > 0) {
834 POSE_TR(pose_tr, pose);
835 printf("Pose size = [4x4]\n");
836 //std::cout << "Pose size = [4x4]\n";
837 for (j = 0; j < 4; j++) {
838 Debug_Array(pose_tr + j * 4, 4);
839 printf("\n");
840 //std::cout << "\n";
841 }
842 }
843 else {
844 POSE_2_XYZWPR(xyzwpr, pose);
845 //std::cout << "XYZWPR = [ ";
846 printf("XYZWPR = [ ");
847 Debug_Array(xyzwpr, 6);
848 printf(" ]\n");
849 //std::cout << " ]\n";
850 }
851}
852*/
853
The Mat class represents a 4x4 pose matrix. The main purpose of this object is to represent a pose in...
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.
bool FromString(const QString &str)
Set the matrix given a XYZRPW string array (6-values)
double _valid
Flags if a matrix is not valid.
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).
int GetValues(double *joints)
GetValues.
tJoints(int ndofs=0)
tJoints
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.
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
double * Data()
const double * ValuesD() const
Joint values.
double _Values[RDK_SIZE_JOINTS_MAX]
joint values (doubles, used to store the joint values)
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)
const float * ValuesF() const
Joint values.
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...
The tMatrix2D struct represents a variable size 2d Matrix. Use the Matrix2D_... functions to oeprate ...
double * data
Pointer to the data.
int * size
Pointer to the size array.
int allocatedSize
Allocated size.
int numDimensions
Number of dimensions (usually 2)