00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #include <math.h>
00055 #include "posemath.h"
00056 #include "genhexkins.h"
00057 #include "emcmot.h"
00058
00059
00060
00061
00062
00063
00064
00065 static int MatInvert(double J[][NUM_STRUTS], double InvJ[][NUM_STRUTS])
00066 {
00067 double JAug[NUM_STRUTS][12], m, temp;
00068 int j, k, n;
00069
00070
00071
00072
00073
00074
00075 for (j=0; j<=5; ++j){
00076 for (k=0; k<=5; ++k){
00077 JAug[j][k] = J[j][k];
00078 }
00079 for(k=6; k<=11; ++k){
00080 if (k-6 == j){
00081 JAug[j][k]=1;
00082 }
00083 else{
00084 JAug[j][k]=0;
00085 }
00086 }
00087 }
00088
00089
00090 for (k=0; k<=4; ++k){
00091 if ((JAug[k][k]< 0.01) && (JAug[k][k] > -0.01)){
00092 for (j=k+1;j<=5; ++j){
00093 if ((JAug[j][k]>0.01) || (JAug[j][k]<-0.01)){
00094 for (n=0; n<=11;++n){
00095 temp = JAug[k][n];
00096 JAug[k][n] = JAug[j][n];
00097 JAug[j][n] = temp;
00098 }
00099 break;
00100 }
00101 }
00102 }
00103 for (j=k+1; j<=5; ++j){
00104 m = -JAug[j][k] / JAug[k][k];
00105 for (n=0; n<=11; ++n){
00106 JAug[j][n]=JAug[j][n] + m*JAug[k][n];
00107 if ((JAug[j][n] < 0.000001) && (JAug[j][n] > -0.000001)){
00108 JAug[j][n] = 0;
00109 }
00110 }
00111 }
00112 }
00113
00114
00115 for (j=0; j<=5; ++j){
00116 m=1/JAug[j][j];
00117 for(k=0; k<=11; ++k){
00118 JAug[j][k] = m * JAug[j][k];
00119 }
00120 }
00121
00122
00123 for (k=5; k>=0; --k){
00124 for(j=k-1; j>=0; --j){
00125 m = -JAug[j][k]/JAug[k][k];
00126 for (n=0; n<=11; ++n){
00127 JAug[j][n] = JAug[j][n] + m * JAug[k][n];
00128 }
00129 }
00130 }
00131
00132
00133 for (j=0; j<=5; ++j){
00134 for (k=0; k<=5; ++k){
00135 InvJ[j][k] = JAug[j][k+6];
00136
00137 }
00138 }
00139
00140 return 0;
00141 }
00142
00143
00144
00145
00146
00147
00148
00149 static void MatMult(double J[][6], const double x[], double Ans[])
00150 {
00151 int j, k;
00152 for (j=0; j<=5; ++j){
00153 Ans[j] = 0;
00154 for (k=0; k<=5; ++k){
00155 Ans[j] = J[j][k]*x[k]+Ans[j];
00156 }
00157 }
00158 }
00159
00160
00161 static PmCartesian b[6] = {{BASE_0_X, BASE_0_Y, BASE_0_Z},
00162 {BASE_1_X, BASE_1_Y, BASE_1_Z},
00163 {BASE_2_X, BASE_2_Y, BASE_2_Z},
00164 {BASE_3_X, BASE_3_Y, BASE_3_Z},
00165 {BASE_4_X, BASE_4_Y, BASE_4_Z},
00166 {BASE_5_X, BASE_5_Y, BASE_5_Z}};
00167
00168 static PmCartesian a[6] = {{PLATFORM_0_X, PLATFORM_0_Y, PLATFORM_0_Z},
00169 {PLATFORM_1_X, PLATFORM_1_Y, PLATFORM_1_Z},
00170 {PLATFORM_2_X, PLATFORM_2_Y, PLATFORM_2_Z},
00171 {PLATFORM_3_X, PLATFORM_3_Y, PLATFORM_3_Z},
00172 {PLATFORM_4_X, PLATFORM_4_Y, PLATFORM_4_Z},
00173 {PLATFORM_5_X, PLATFORM_5_Y, PLATFORM_5_Z}};
00174
00175 int genhexSetParams(const PmCartesian base[], const PmCartesian platform[])
00176 {
00177 int t;
00178
00179 for (t = 0; t < 6; t++) {
00180 b[t] = base[t];
00181 a[t] = platform[t];
00182 }
00183
00184 return 0;
00185 }
00186
00187 int genhexGetParams(PmCartesian base[], PmCartesian platform[])
00188 {
00189 int t;
00190
00191 for (t = 0; t < 6; t++) {
00192 base[t] = b[t];
00193 platform[t] = b[t];
00194 }
00195
00196 return 0;
00197 }
00198
00199
00200
00201 static int JInvMat(const EmcPose * pos,
00202 double InverseJacobian[][NUM_STRUTS])
00203 {
00204 int i;
00205 PmRpy rpy;
00206 PmRotationMatrix RMatrix;
00207 PmCartesian aw, RMatrix_a;
00208 PmCartesian InvKinStrutVect,InvKinStrutVectUnit;
00209 PmCartesian RMatrix_a_cross_Strut;
00210
00211
00212 rpy.r = pos->a * PM_PI / 180.0;
00213 rpy.p = pos->b * PM_PI / 180.0;
00214 rpy.y = pos->c * PM_PI / 180.0;
00215 pmRpyMatConvert(rpy, &RMatrix);
00216
00217
00218 for (i = 0; i < NUM_STRUTS; i++) {
00219
00220 pmMatCartMult(RMatrix, a[i], &RMatrix_a);
00221 pmCartCartAdd(pos->tran, RMatrix_a, &aw);
00222 pmCartCartSub(aw, b[i], &InvKinStrutVect);
00223
00224
00225 if (0 != pmCartUnit(InvKinStrutVect, &InvKinStrutVectUnit)) {
00226 return -1;
00227 }
00228 pmCartCartCross(RMatrix_a, InvKinStrutVectUnit, &RMatrix_a_cross_Strut);
00229
00230
00231 InverseJacobian[i][0] = InvKinStrutVectUnit.x;
00232 InverseJacobian[i][1] = InvKinStrutVectUnit.y;
00233 InverseJacobian[i][2] = InvKinStrutVectUnit.z;
00234 InverseJacobian[i][3] = RMatrix_a_cross_Strut.x;
00235 InverseJacobian[i][4] = RMatrix_a_cross_Strut.y;
00236 InverseJacobian[i][5] = RMatrix_a_cross_Strut.z;
00237 }
00238
00239 return 0;
00240 }
00241
00242 int jacobianInverse(const EmcPose * pos,
00243 const EmcPose * vel,
00244 const double * joints,
00245 double * jointvels)
00246 {
00247 double InverseJacobian[NUM_STRUTS][NUM_STRUTS];
00248 double velmatrix[6];
00249
00250 if (0 != JInvMat(pos, InverseJacobian)) {
00251 return -1;
00252 }
00253
00254
00255 velmatrix[0] = vel->tran.x;
00256 velmatrix[1] = vel->tran.y;
00257 velmatrix[2] = vel->tran.z;
00258 velmatrix[3] = vel->a;
00259 velmatrix[4] = vel->b;
00260 velmatrix[5] = vel->c;
00261 MatMult(InverseJacobian, velmatrix, jointvels);
00262
00263 return 0;
00264 }
00265
00266
00267
00268
00269
00270 int jacobianForward(const double * joints,
00271 const double * jointvels,
00272 const EmcPose * pos,
00273 EmcPose * vel)
00274 {
00275 double InverseJacobian[NUM_STRUTS][NUM_STRUTS];
00276 double Jacobian[NUM_STRUTS][NUM_STRUTS];
00277 double velmatrix[6];
00278
00279 if (0 != JInvMat(pos, InverseJacobian)) {
00280 return -1;
00281 }
00282 if (0 != MatInvert(InverseJacobian, Jacobian)) {
00283 return -1;
00284 }
00285
00286
00287 MatMult(Jacobian, jointvels, velmatrix);
00288 vel->tran.x = velmatrix[0];
00289 vel->tran.y = velmatrix[1];
00290 vel->tran.z = velmatrix[2];
00291 vel->a = velmatrix[3];
00292 vel->b = velmatrix[4];
00293 vel->c = velmatrix[5];
00294
00295 return 0;
00296 }
00297
00298
00299
00300
00301
00302
00303
00304 int kinematicsForward(const double * joints,
00305 EmcPose * pos,
00306 const KINEMATICS_FORWARD_FLAGS * fflags,
00307 KINEMATICS_INVERSE_FLAGS * iflags)
00308 {
00309 PmCartesian aw;
00310 PmCartesian InvKinStrutVect,InvKinStrutVectUnit;
00311 PmCartesian q_trans, RMatrix_a, RMatrix_a_cross_Strut;
00312
00313 double Jacobian[NUM_STRUTS][NUM_STRUTS];
00314 double InverseJacobian[NUM_STRUTS][NUM_STRUTS];
00315 double InvKinStrutLength, StrutLengthDiff[NUM_STRUTS];
00316 double delta[NUM_STRUTS];
00317 double conv_err = 1.0;
00318
00319 PmRotationMatrix RMatrix;
00320 PmRpy q_RPY;
00321
00322 int iterate = 1;
00323 int i;
00324 int iteration = 0;
00325 int retval = 0;
00326
00327 #define HIGH_CONV_CRITERION (1e-12)
00328 #define MEDIUM_CONV_CRITERION (1e-5)
00329 #define LOW_CONV_CRITERION (1e-3)
00330 #define MEDIUM_CONV_ITERATIONS 50
00331 #define LOW_CONV_ITERATIONS 100
00332 #define FAIL_CONV_ITERATIONS 150
00333 #define LARGE_CONV_ERROR 10000
00334 double conv_criterion = HIGH_CONV_CRITERION;
00335
00336
00337
00338
00339 if (joints[0] <= 0.0 ||
00340 joints[1] <= 0.0 ||
00341 joints[2] <= 0.0 ||
00342 joints[3] <= 0.0 ||
00343 joints[4] <= 0.0 ||
00344 joints[5] <= 0.0) {
00345 return -1;
00346 }
00347
00348
00349 q_RPY.r = pos->a * PM_PI / 180.0;
00350 q_RPY.p = pos->b * PM_PI / 180.0;
00351 q_RPY.y = pos->c * PM_PI / 180.0;
00352
00353
00354 q_trans.x = pos->tran.x;
00355 q_trans.y = pos->tran.y;
00356 q_trans.z = pos->tran.z;
00357
00358
00359 while (iterate) {
00360
00361 if ((conv_err > +LARGE_CONV_ERROR) ||
00362 (conv_err < -LARGE_CONV_ERROR)) {
00363
00364 return -2;
00365 };
00366
00367 iteration++;
00368
00369 #if 0
00370
00371
00372 if (iteration == MEDIUM_CONV_ITERATIONS) {
00373 conv_criterion = MEDIUM_CONV_CRITERION;
00374 retval = -3;
00375
00376 }
00377
00378 if (iteration == LOW_CONV_ITERATIONS) {
00379 conv_criterion = LOW_CONV_CRITERION;
00380 retval = -4;
00381
00382 }
00383 #endif
00384
00385
00386
00387 if (iteration > FAIL_CONV_ITERATIONS) {
00388
00389 return -5;
00390 }
00391
00392
00393 pmRpyMatConvert(q_RPY, &RMatrix);
00394
00395
00396
00397
00398 for (i = 0; i < NUM_STRUTS; i++) {
00399 pmMatCartMult(RMatrix, a[i], &RMatrix_a);
00400 pmCartCartAdd(q_trans, RMatrix_a, &aw);
00401 pmCartCartSub(aw,b[i], &InvKinStrutVect);
00402 if (0 != pmCartUnit(InvKinStrutVect, &InvKinStrutVectUnit)) {
00403 return -1;
00404 }
00405 pmCartMag(InvKinStrutVect, &InvKinStrutLength);
00406 StrutLengthDiff[i] = InvKinStrutLength - joints[i];
00407
00408
00409 pmCartCartCross(RMatrix_a, InvKinStrutVectUnit, &RMatrix_a_cross_Strut);
00410
00411
00412 InverseJacobian[i][0] = InvKinStrutVectUnit.x;
00413 InverseJacobian[i][1] = InvKinStrutVectUnit.y;
00414 InverseJacobian[i][2] = InvKinStrutVectUnit.z;
00415 InverseJacobian[i][3] = RMatrix_a_cross_Strut.x;
00416 InverseJacobian[i][4] = RMatrix_a_cross_Strut.y;
00417 InverseJacobian[i][5] = RMatrix_a_cross_Strut.z;
00418 }
00419
00420
00421 MatInvert(InverseJacobian, Jacobian);
00422
00423
00424 MatMult(Jacobian, StrutLengthDiff, delta);
00425
00426
00427 q_trans.x -= delta[0];
00428 q_trans.y -= delta[1];
00429 q_trans.z -= delta[2];
00430 q_RPY.r -= delta[3];
00431 q_RPY.p -= delta[4];
00432 q_RPY.y -= delta[5];
00433
00434
00435 conv_err = 0.0;
00436 for (i = 0; i < NUM_STRUTS; i++) {
00437 conv_err += fabs(StrutLengthDiff[i]);
00438 }
00439
00440
00441 iterate = 0;
00442 for (i = 0; i < NUM_STRUTS; i++) {
00443 if (fabs(StrutLengthDiff[i]) > conv_criterion) {
00444 iterate = 1;
00445 }
00446 }
00447 }
00448
00449
00450 pos->a = q_RPY.r * 180.0 / PM_PI;
00451 pos->b = q_RPY.p * 180.0 / PM_PI;
00452 pos->c = q_RPY.y * 180.0 / PM_PI;
00453
00454
00455 pos->tran.x = q_trans.x;
00456 pos->tran.y = q_trans.y;
00457 pos->tran.z = q_trans.z;
00458
00459 return retval;
00460 }
00461
00462
00463
00464 int kinematicsInverse(const EmcPose * pos,
00465 double * joints,
00466 const KINEMATICS_INVERSE_FLAGS * iflags,
00467 KINEMATICS_FORWARD_FLAGS * fflags)
00468 {
00469 PmCartesian aw, temp;
00470 PmRotationMatrix RMatrix;
00471 PmRpy rpy;
00472 int i;
00473
00474
00475 rpy.r = pos->a * PM_PI / 180.0;
00476 rpy.p = pos->b * PM_PI / 180.0;
00477 rpy.y = pos->c * PM_PI / 180.0;
00478 pmRpyMatConvert(rpy, &RMatrix);
00479
00480
00481 for (i = 0; i < NUM_STRUTS; i++) {
00482
00483
00484 pmMatCartMult(RMatrix, a[i], &temp);
00485 pmCartCartAdd(pos->tran, temp, &aw);
00486
00487
00488 pmCartCartSub(aw, b[i], &temp);
00489 pmCartMag(temp, &joints[i]);
00490 }
00491
00492 return 0;
00493 }
00494
00495
00496
00497
00498
00499
00500 int kinematicsHome(EmcPose * world,
00501 double * joint,
00502 KINEMATICS_FORWARD_FLAGS * fflags,
00503 KINEMATICS_INVERSE_FLAGS * iflags)
00504 {
00505 *fflags = 0;
00506 *iflags = 0;
00507
00508 return kinematicsInverse(world, joint, iflags, fflags);
00509 }
00510
00511 KINEMATICS_TYPE kinematicsType()
00512 {
00513 #if 1
00514 return KINEMATICS_BOTH;
00515 #else
00516 return KINEMATICS_INVERSE_ONLY;
00517 #endif
00518 }
00519
00520 #ifdef MAIN
00521
00522 #include <stdio.h>
00523
00524 #include <sys/time.h>
00525 #include <unistd.h>
00526
00527 static double timestamp()
00528 {
00529 struct timeval tp;
00530
00531 if (0 != gettimeofday(&tp, NULL)) {
00532 return 0.0;
00533 }
00534 return ((double) tp.tv_sec) + ((double) tp.tv_usec) / 1000000.0;
00535 }
00536
00537 int main(int argc, char *argv[])
00538 {
00539 #define BUFFERLEN 256
00540 char buffer[BUFFERLEN];
00541 int inverse = 1;
00542 int jacobian = 0;
00543 EmcPose pos = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
00544 EmcPose vel = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
00545 double joints[6] = {0.0};
00546 double jointvels[6] = {0.0};
00547 KINEMATICS_INVERSE_FLAGS iflags = 0;
00548 KINEMATICS_FORWARD_FLAGS fflags = 0;
00549 int t;
00550 int retval;
00551 #define ITERATIONS 100000
00552 double start, end;
00553
00554
00555 if (argc == 8) {
00556 if (argv[1][0] == 'f') {
00557
00558 for (t = 0; t < 6; t++) {
00559 if (1 != sscanf(argv[t + 2], "%lf", &joints[t])) {
00560 fprintf(stderr, "bad value: %s\n", argv[t + 2]);
00561 return 1;
00562 }
00563 }
00564 inverse = 0;
00565 }
00566 else if (argv[1][0] == 'i') {
00567
00568 if (1 != sscanf(argv[2], "%lf", &pos.tran.x)) {
00569 fprintf(stderr, "bad value: %s\n", argv[2]);
00570 return 1;
00571 }
00572 if (1 != sscanf(argv[3], "%lf", &pos.tran.y)) {
00573 fprintf(stderr, "bad value: %s\n", argv[3]);
00574 return 1;
00575 }
00576 if (1 != sscanf(argv[4], "%lf", &pos.tran.z)) {
00577 fprintf(stderr, "bad value: %s\n", argv[4]);
00578 return 1;
00579 }
00580 if (1 != sscanf(argv[5], "%lf", &pos.a)) {
00581 fprintf(stderr, "bad value: %s\n", argv[5]);
00582 return 1;
00583 }
00584 if (1 != sscanf(argv[6], "%lf", &pos.b)) {
00585 fprintf(stderr, "bad value: %s\n", argv[6]);
00586 return 1;
00587 }
00588 if (1 != sscanf(argv[7], "%lf", &pos.c)) {
00589 fprintf(stderr, "bad value: %s\n", argv[7]);
00590 return 1;
00591 }
00592 inverse = 1;
00593 }
00594 else {
00595 fprintf(stderr, "syntax: %s {i|f # # # # # #}\n", argv[0]);
00596 return 1;
00597 }
00598
00599
00600 if (inverse == 0) {
00601 do {
00602 printf("initial estimate for Cartesian position, xyzrpw: ");
00603 fflush(stdout);
00604 if (NULL == fgets(buffer, BUFFERLEN, stdin)) {
00605 return 0;
00606 }
00607 } while (6 != sscanf(buffer, "%lf %lf %lf %lf %lf %lf",
00608 &pos.tran.x,
00609 &pos.tran.y,
00610 &pos.tran.z,
00611 &pos.a,
00612 &pos.b,
00613 &pos.c));
00614 }
00615
00616 start = timestamp();
00617 for (t = 0; t < ITERATIONS; t++) {
00618 if (inverse) {
00619 retval = kinematicsInverse(&pos, joints, &iflags, &fflags);
00620 if (0 != retval) {
00621 printf("inv kins error %d\n", retval);
00622 break;
00623 }
00624 }
00625 else {
00626 retval = kinematicsForward(joints, &pos, &fflags, &iflags);
00627 if (0 != retval) {
00628 printf("fwd kins error %d\n", retval);
00629 break;
00630 }
00631 }
00632 }
00633 end = timestamp();
00634
00635 printf("calculation time: %f secs\n",
00636 (end - start) / ((double) ITERATIONS));
00637 return 0;
00638 }
00639
00640
00641 while (! feof(stdin)) {
00642 if (inverse) {
00643 if (jacobian) {
00644 printf("jinv> ");
00645 }
00646 else {
00647 printf("inv> ");
00648 }
00649 }
00650 else {
00651 if (jacobian) {
00652 printf("jfwd> ");
00653 }
00654 else {
00655 printf("fwd> ");
00656 }
00657 }
00658 fflush(stdout);
00659
00660 if (NULL == fgets(buffer, BUFFERLEN, stdin)) {
00661 break;
00662 }
00663
00664 if (buffer[0] == 'i') {
00665 inverse = 1;
00666 continue;
00667 }
00668 else if (buffer[0] == 'f') {
00669 inverse = 0;
00670 continue;
00671 }
00672 else if (buffer[0] == 'j') {
00673 jacobian = ! jacobian;
00674 continue;
00675 }
00676 else if (buffer[0] == 'q') {
00677 break;
00678 }
00679
00680 if (inverse) {
00681 if (jacobian) {
00682 if (12 != sscanf(buffer, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
00683 &pos.tran.x,
00684 &pos.tran.y,
00685 &pos.tran.z,
00686 &pos.a,
00687 &pos.b,
00688 &pos.c,
00689 &vel.tran.x,
00690 &vel.tran.y,
00691 &vel.tran.z,
00692 &vel.a,
00693 &vel.b,
00694 &vel.c)) {
00695 printf("?\n");
00696 }
00697 else {
00698 retval = jacobianInverse(&pos, &vel, joints, jointvels);
00699 printf("%f %f %f %f %f %f\n",
00700 jointvels[0],
00701 jointvels[1],
00702 jointvels[2],
00703 jointvels[3],
00704 jointvels[4],
00705 jointvels[5]);
00706 if (0 != retval) {
00707 printf("inv Jacobian error %d\n", retval);
00708 }
00709 else {
00710 retval = jacobianForward(joints, jointvels, &pos, &vel);
00711 printf("%f %f %f %f %f %f\n",
00712 vel.tran.x,
00713 vel.tran.y,
00714 vel.tran.z,
00715 vel.a,
00716 vel.b,
00717 vel.c);
00718 if (0 != retval) {
00719 printf("fwd kins error %d\n", retval);
00720 }
00721 }
00722 }
00723 }
00724 else {
00725 if (6 != sscanf(buffer, "%lf %lf %lf %lf %lf %lf",
00726 &pos.tran.x,
00727 &pos.tran.y,
00728 &pos.tran.z,
00729 &pos.a,
00730 &pos.b,
00731 &pos.c)) {
00732 printf("?\n");
00733 }
00734 else {
00735 retval = kinematicsInverse(&pos, joints, &iflags, &fflags);
00736 printf("%f %f %f %f %f %f\n",
00737 joints[0],
00738 joints[1],
00739 joints[2],
00740 joints[3],
00741 joints[4],
00742 joints[5]);
00743 if (0 != retval) {
00744 printf("inv kins error %d\n", retval);
00745 }
00746 else {
00747 retval = kinematicsForward(joints, &pos, &fflags, &iflags);
00748 printf("%f %f %f %f %f %f\n",
00749 pos.tran.x,
00750 pos.tran.y,
00751 pos.tran.z,
00752 pos.a,
00753 pos.b,
00754 pos.c);
00755 if (0 != retval) {
00756 printf("fwd kins error %d\n", retval);
00757 }
00758 }
00759 }
00760 }
00761 }
00762 else {
00763 if (jacobian) {
00764 if (12 != sscanf(buffer, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
00765 &joints[0],
00766 &joints[1],
00767 &joints[2],
00768 &joints[3],
00769 &joints[4],
00770 &joints[5],
00771 &jointvels[0],
00772 &jointvels[1],
00773 &jointvels[2],
00774 &jointvels[3],
00775 &jointvels[4],
00776 &jointvels[5])) {
00777 printf("?\n");
00778 }
00779 else {
00780 retval = jacobianForward(joints, jointvels, &pos, &vel);
00781 printf("%f %f %f %f %f %f\n",
00782 vel.tran.x,
00783 vel.tran.y,
00784 vel.tran.z,
00785 vel.a,
00786 vel.b,
00787 vel.c);
00788 if (0 != retval) {
00789 printf("fwd kins error %d\n", retval);
00790 }
00791 else {
00792 retval = jacobianInverse(&pos, &vel, joints, jointvels);
00793 printf("%f %f %f %f %f %f\n",
00794 jointvels[0],
00795 jointvels[1],
00796 jointvels[2],
00797 jointvels[3],
00798 jointvels[4],
00799 jointvels[5]);
00800 if (0 != retval) {
00801 printf("inv kins error %d\n", retval);
00802 }
00803 }
00804 }
00805 }
00806 else {
00807 if (6 != sscanf(buffer, "%lf %lf %lf %lf %lf %lf",
00808 &joints[0],
00809 &joints[1],
00810 &joints[2],
00811 &joints[3],
00812 &joints[4],
00813 &joints[5])) {
00814 printf("?\n");
00815 }
00816 else {
00817 retval = kinematicsForward(joints, &pos, &fflags, &iflags);
00818 printf("%f %f %f %f %f %f\n",
00819 pos.tran.x,
00820 pos.tran.y,
00821 pos.tran.z,
00822 pos.a,
00823 pos.b,
00824 pos.c);
00825 if (0 != retval) {
00826 printf("fwd kins error %d\n", retval);
00827 }
00828 else {
00829 retval = kinematicsInverse(&pos, joints, &iflags, &fflags);
00830 printf("%f %f %f %f %f %f\n",
00831 joints[0],
00832 joints[1],
00833 joints[2],
00834 joints[3],
00835 joints[4],
00836 joints[5]);
00837 if (0 != retval) {
00838 printf("inv kins error %d\n", retval);
00839 }
00840 }
00841 }
00842 }
00843 }
00844 }
00845
00846 return 0;
00847
00848 #undef ITERATIONS
00849 #undef BUFFERLEN
00850 }
00851
00852 #endif
00853