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
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 #include "robot.h"
00095 #include <time.h>
00096 #ifdef __WATCOMC__
00097 #include <strstrea.h>
00098 #else
00099 #include <sstream>
00100 #endif
00101
00102 using namespace std;
00103
00104 #ifdef use_namespace
00105 namespace ROBOOP {
00106 using namespace NEWMAT;
00107 #endif
00108
00109
00110 static const char rcsid[] __UNUSED__ = "$Id: robot.cpp,v 1.25 2007/11/11 23:57:24 ejt Exp $";
00111
00112
00113 Real fourbyfourident[] = {1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0};
00114
00115
00116 Real threebythreeident[] ={1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0};
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 Link::Link(const int jt, const Real it, const Real id, const Real ia, const Real ial,
00130 const Real it_min, const Real it_max, const Real it_off, const Real mass,
00131 const Real cmx, const Real cmy, const Real cmz, const Real ixx, const Real ixy,
00132 const Real ixz, const Real iyy, const Real iyz, const Real izz, const Real iIm,
00133 const Real iGr, const Real iB, const Real iCf, const bool dh,
00134 const bool min_inertial_parameters):
00135 R(3,3),
00136 qp(0),
00137 qpp(0),
00138 joint_type(jt),
00139 theta(it),
00140 d(id),
00141 a(ia),
00142 alpha(ial),
00143 theta_min(it_min),
00144 theta_max(it_max),
00145 joint_offset(it_off),
00146 DH(dh),
00147 min_para(min_inertial_parameters),
00148 r(),
00149 p(3),
00150 m(mass),
00151 Im(iIm),
00152 Gr(iGr),
00153 B(iB),
00154 Cf(iCf),
00155 mc(),
00156 I(3,3),
00157 immobile(false)
00158 {
00159 if (joint_type == 0)
00160 theta += joint_offset;
00161 else
00162 d += joint_offset;
00163 Real ct, st, ca, sa;
00164 ct = cos(theta);
00165 st = sin(theta);
00166 ca = cos(alpha);
00167 sa = sin(alpha);
00168
00169 qp = qpp = 0.0;
00170
00171 if (DH)
00172 {
00173 R(1,1) = ct;
00174 R(2,1) = st;
00175 R(3,1) = 0.0;
00176 R(1,2) = -ca*st;
00177 R(2,2) = ca*ct;
00178 R(3,2) = sa;
00179 R(1,3) = sa*st;
00180 R(2,3) = -sa*ct;
00181 R(3,3) = ca;
00182
00183 p(1) = a*ct;
00184 p(2) = a*st;
00185 p(3) = d;
00186 }
00187 else
00188 {
00189 R(1,1) = ct;
00190 R(2,1) = st*ca;
00191 R(3,1) = st*sa;
00192 R(1,2) = -st;
00193 R(2,2) = ca*ct;
00194 R(3,2) = sa*ct;
00195 R(1,3) = 0;
00196 R(2,3) = -sa;
00197 R(3,3) = ca;
00198
00199 p(1) = a;
00200 p(2) = -sa*d;
00201 p(3) = ca*d;
00202 }
00203
00204 if (min_para)
00205 {
00206 mc = ColumnVector(3);
00207 mc(1) = cmx;
00208 mc(2) = cmy;
00209 mc(3) = cmz;
00210 }
00211 else
00212 {
00213 r = ColumnVector(3);
00214 r(1) = cmx;
00215 r(2) = cmy;
00216 r(3) = cmz;
00217 }
00218
00219 I(1,1) = ixx;
00220 I(1,2) = I(2,1) = ixy;
00221 I(1,3) = I(3,1) = ixz;
00222 I(2,2) = iyy;
00223 I(2,3) = I(3,2) = iyz;
00224 I(3,3) = izz;
00225 }
00226
00227 Link::Link(const Link & x)
00228
00229 :
00230 R(x.R),
00231 qp(x.qp),
00232 qpp(x.qpp),
00233 joint_type(x.joint_type),
00234 theta(x.theta),
00235 d(x.d),
00236 a(x.a),
00237 alpha(x.alpha),
00238 theta_min(x.theta_min),
00239 theta_max(x.theta_max),
00240 joint_offset(x.joint_offset),
00241 DH(x.DH),
00242 min_para(x.min_para),
00243 r(x.r),
00244 p(x.p),
00245 m(x.m),
00246 Im(x.Im),
00247 Gr(x.Gr),
00248 B(x.B),
00249 Cf(x.Cf),
00250 mc(x.mc),
00251 I(x.I),
00252 immobile(x.immobile)
00253 {
00254 }
00255
00256 Link & Link::operator=(const Link & x)
00257
00258 {
00259 joint_type = x.joint_type;
00260 theta = x.theta;
00261 qp = x.qp;
00262 qpp = x.qpp;
00263 d = x.d;
00264 a = x.a;
00265 alpha = x.alpha;
00266 theta_min = x.theta_min;
00267 theta_max = x.theta_max;
00268 joint_offset = x.joint_offset;
00269 R = x.R;
00270 p = x.p;
00271 m = x.m;
00272 r = x.r;
00273 mc = x.mc;
00274 I = x.I;
00275 Im = x.Im;
00276 Gr = x.Gr;
00277 B = x.B;
00278 Cf = x.Cf;
00279 DH = x.DH;
00280 min_para = x.min_para;
00281 immobile = x.immobile;
00282 return *this;
00283 }
00284
00285 void Link::transform(const Real q)
00286
00287 {
00288 if (DH)
00289 {
00290 if(joint_type == 0)
00291 {
00292 Real ct, st, ca, sa;
00293 Real nt=q + joint_offset;
00294 if(theta==nt)
00295 return;
00296 theta=nt;
00297 ct = cos(theta);
00298 st = sin(theta);
00299 ca = R(3,3);
00300 sa = R(3,2);
00301
00302 R(1,1) = ct;
00303 R(2,1) = st;
00304 R(1,2) = -ca*st;
00305 R(2,2) = ca*ct;
00306 R(1,3) = sa*st;
00307 R(2,3) = -sa*ct;
00308 p(1) = a*ct;
00309 p(2) = a*st;
00310 }
00311 else
00312 p(3) = d = q + joint_offset;
00313 }
00314 else
00315 {
00316 Real ca, sa;
00317 ca = R(3,3);
00318 sa = -R(2,3);
00319 if(joint_type == 0)
00320 {
00321 Real ct, st;
00322 Real nt=q + joint_offset;
00323 if(theta==nt)
00324 return;
00325 theta=nt;
00326 ct = cos(theta);
00327 st = sin(theta);
00328
00329 R(1,1) = ct;
00330 R(2,1) = st*ca;
00331 R(3,1) = st*sa;
00332 R(1,2) = -st;
00333 R(2,2) = ca*ct;
00334 R(3,2) = sa*ct;
00335 R(1,3) = 0;
00336 }
00337 else
00338 {
00339 d = q + joint_offset;
00340 p(2) = -sa*d;
00341 p(3) = ca*d;
00342 }
00343 }
00344 }
00345
00346 Real Link::get_q(void) const
00347
00348
00349
00350
00351
00352 {
00353 if(joint_type == 0)
00354 return theta - joint_offset;
00355 else
00356 return d - joint_offset;
00357 }
00358
00359
00360 void Link::set_r(const ColumnVector & r_)
00361
00362 {
00363 if(r_.Nrows() == 3)
00364 r = r_;
00365 else
00366 cerr << "Link::set_r: wrong size in input vector." << endl;
00367 }
00368
00369 void Link::set_mc(const ColumnVector & mc_)
00370
00371 {
00372 if(mc_.Nrows() == 3)
00373 mc = mc_;
00374 else
00375 cerr << "Link::set_mc: wrong size in input vector." << endl;
00376 }
00377
00378
00379
00380
00381
00382 void Link::set_I(const Matrix & I_)
00383 {
00384 if( (I_.Nrows() == 3) && (I_.Ncols() == 3) )
00385 I = I_;
00386 else
00387 cerr << "Link::set_r: wrong size in input vector." << endl;
00388 }
00389
00390 Robot_basic::Robot_basic(const Matrix & dhinit, const bool dh_parameter,
00391 const bool min_inertial_para)
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 : w(NULL), wp(NULL), vp(NULL), a(NULL), f(NULL), f_nv(NULL), n(NULL), n_nv(NULL),
00402 F(NULL), N(NULL), p(NULL), pp(NULL), dw(NULL), dwp(NULL), dvp(NULL), da(NULL),
00403 df(NULL), dn(NULL), dF(NULL), dN(NULL), dp(NULL), z0(3), gravity(3), R(NULL),
00404 links(NULL), robotType(DEFAULT), dof(0), fix(0)
00405 {
00406 int ndof=0, i;
00407
00408 gravity = 0.0;
00409 gravity(3) = 9.81;
00410 z0(1) = z0(2) = 0.0; z0(3) = 1.0;
00411 fix = 0;
00412 for(i = 1; i <= dhinit.Nrows(); i++)
00413 if(dhinit(i,1) == 2)
00414 {
00415 if (i == dhinit.Nrows())
00416 fix = 1;
00417 else
00418 error("Fix link can only be on the last one");
00419 }
00420 else
00421 ndof++;
00422
00423 if(ndof < 1)
00424 error("Number of degree of freedom must be greater or equal to 1");
00425
00426 dof = ndof;
00427
00428 try
00429 {
00430 links = new Link[dof+fix];
00431 links = links-1;
00432 w = new ColumnVector[dof+1];
00433 wp = new ColumnVector[dof+1];
00434 vp = new ColumnVector[dof+fix+1];
00435 a = new ColumnVector[dof+1];
00436 f = new ColumnVector[dof+1];
00437 f_nv = new ColumnVector[dof+1];
00438 n = new ColumnVector[dof+1];
00439 n_nv = new ColumnVector[dof+1];
00440 F = new ColumnVector[dof+1];
00441 N = new ColumnVector[dof+1];
00442 p = new ColumnVector[dof+fix+1];
00443 pp = new ColumnVector[dof+fix+1];
00444 dw = new ColumnVector[dof+1];
00445 dwp = new ColumnVector[dof+1];
00446 dvp = new ColumnVector[dof+1];
00447 da = new ColumnVector[dof+1];
00448 df = new ColumnVector[dof+1];
00449 dn = new ColumnVector[dof+1];
00450 dF = new ColumnVector[dof+1];
00451 dN = new ColumnVector[dof+1];
00452 dp = new ColumnVector[dof+1];
00453 R = new Matrix[dof+fix+1];
00454 }
00455 catch(bad_alloc ex)
00456 {
00457 cerr << "Robot_basic constructor : new ran out of memory" << endl;
00458 exit(1);
00459 }
00460
00461 for(i = 0; i <= dof; i++)
00462 {
00463 w[i] = ColumnVector(3);
00464 w[i] = 0.0;
00465 wp[i] = ColumnVector(3);
00466 wp[i] = 0.0;
00467 vp[i] = ColumnVector(3);
00468 dw[i] = ColumnVector(3);
00469 dw[i] = 0.0;
00470 dwp[i] = ColumnVector(3);
00471 dwp[i] = 0.0;
00472 dvp[i] = ColumnVector(3);
00473 dvp[i] = 0.0;
00474 }
00475 for(i = 0; i <= dof+fix; i++)
00476 {
00477 R[i] = Matrix(3,3);
00478 R[i] << threebythreeident;
00479 p[i] = ColumnVector(3);
00480 p[i] = 0.0;
00481 pp[i] = p[i];
00482 }
00483
00484 switch (dhinit.Ncols()){
00485 case 5:
00486 for(i = 1; i <= dof+fix; i++)
00487 {
00488 links[i] = Link((int) dhinit(i,1), dhinit(i,2), dhinit(i,3),
00489 dhinit(i,4), dhinit(i,5), 0, 0, 0, 0, 0, 0, 0,
00490 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dh_parameter, min_inertial_para);
00491 }
00492 break;
00493 case 7:
00494 for(i = 1; i <= dof+fix; i++)
00495 {
00496 links[i] = Link((int) dhinit(i,1), dhinit(i,2), dhinit(i,3),
00497 dhinit(i,4), dhinit(i,5), dhinit(i,6), dhinit(i,7),
00498 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00499 dh_parameter, min_inertial_para);
00500 }
00501 break;
00502 case 15:
00503 for(i = 1; i <= dof+fix; i++)
00504 {
00505 links[i] = Link((int) dhinit(i,1), dhinit(i,2), dhinit(i,3),
00506 dhinit(i,4), dhinit(i,5), 0, 0, 0, dhinit(i,6), dhinit(i,7),
00507 dhinit(i,8), dhinit(i,9), dhinit(i,10), dhinit(i,11),
00508 dhinit(i,12), dhinit(i,13), dhinit(i,14), dhinit(i,15),
00509 0, 0, 0, 0, dh_parameter, min_inertial_para);
00510 }
00511 break;
00512 case 18:
00513 for(i = 1; i <= dof+fix; i++)
00514 {
00515 links[i] = Link((int) dhinit(i,1), dhinit(i,2), dhinit(i,3),
00516 dhinit(i,4), dhinit(i,5), dhinit(i,6), dhinit(i,7),
00517 dhinit(i,8), dhinit(i,9), dhinit(i,10), dhinit(i,11),
00518 dhinit(i,12), dhinit(i,13), dhinit(i,14), dhinit(i,15),
00519 dhinit(i,16), dhinit(i,17), dhinit(i,18), 0, 0, 0, 0,
00520 dh_parameter, min_inertial_para);
00521 }
00522 break;
00523 case 20:
00524 for(i = 1; i <= dof+fix; i++)
00525 {
00526 links[i] = Link((int) dhinit(i,1), dhinit(i,2), dhinit(i,3),
00527 dhinit(i,4), dhinit(i,5), 0, 0, dhinit(i,6), dhinit(i,7),
00528 dhinit(i,8), dhinit(i,9), dhinit(i,10), dhinit(i,11),
00529 dhinit(i,12), dhinit(i,13), dhinit(i,14), dhinit(i,15),
00530 dhinit(i,16), dhinit(i,17), dhinit(i,18), dhinit(i,19),
00531 dhinit(i,20), dh_parameter, min_inertial_para);
00532 }
00533 break;
00534 case 22:
00535 for(i = 1; i <= dof+fix; i++)
00536 {
00537 links[i] = Link((int) dhinit(i,1), dhinit(i,2), dhinit(i,3),
00538 dhinit(i,4), dhinit(i,5), dhinit(i,6), dhinit(i,7),
00539 dhinit(i,8), dhinit(i,9), dhinit(i,10), dhinit(i,11),
00540 dhinit(i,12), dhinit(i,13), dhinit(i,14), dhinit(i,15),
00541 dhinit(i,16), dhinit(i,17), dhinit(i,18), dhinit(i,19),
00542 dhinit(i,20), dhinit(i,21), dhinit(i,22),
00543 dh_parameter, min_inertial_para);
00544 }
00545 break;
00546 default:
00547 error("Initialisation Matrix does not have 5, ,7, 16 18, 20 or 22 columns.");
00548 }
00549
00550 }
00551
00552 Robot_basic::Robot_basic(const Matrix & initrobot, const Matrix & initmotor,
00553 const bool dh_parameter, const bool min_inertial_para)
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564 : w(NULL), wp(NULL), vp(NULL), a(NULL), f(NULL), f_nv(NULL), n(NULL), n_nv(NULL),
00565 F(), N(NULL), p(NULL), pp(NULL), dw(NULL), dwp(NULL), dvp(NULL), da(NULL),
00566 df(NULL), dn(NULL), dF(NULL), dN(NULL), dp(NULL), z0(3), gravity(3), R(NULL),
00567 links(NULL), robotType(DEFAULT), dof(0), fix(0)
00568 {
00569 int ndof=0, i;
00570
00571 gravity = 0.0;
00572 gravity(3) = 9.81;
00573 z0(1) = z0(2) = 0.0; z0(3) = 1.0;
00574
00575 for(i = 1; i <= initrobot.Nrows(); i++)
00576 if(initrobot(i,1) == 2)
00577 {
00578 if (i == initrobot.Nrows())
00579 fix = 1;
00580 else
00581 error("Fix link can only be on the last one");
00582 }
00583 else
00584 ndof++;
00585
00586 if(ndof < 1)
00587 error("Number of degree of freedom must be greater or equal to 1");
00588 dof = ndof;
00589
00590 try
00591 {
00592 links = new Link[dof+fix];
00593 links = links-1;
00594 w = new ColumnVector[dof+1];
00595 wp = new ColumnVector[dof+1];
00596 vp = new ColumnVector[dof+fix+1];
00597 a = new ColumnVector[dof+1];
00598 f = new ColumnVector[dof+1];
00599 f_nv = new ColumnVector[dof+1];
00600 n = new ColumnVector[dof+1];
00601 n_nv = new ColumnVector[dof+1];
00602 F = new ColumnVector[dof+1];
00603 N = new ColumnVector[dof+1];
00604 p = new ColumnVector[dof+fix+1];
00605 pp = new ColumnVector[dof+fix+1];
00606 dw = new ColumnVector[dof+1];
00607 dwp = new ColumnVector[dof+1];
00608 dvp = new ColumnVector[dof+1];
00609 da = new ColumnVector[dof+1];
00610 df = new ColumnVector[dof+1];
00611 dn = new ColumnVector[dof+1];
00612 dF = new ColumnVector[dof+1];
00613 dN = new ColumnVector[dof+1];
00614 dp = new ColumnVector[dof+1];
00615 R = new Matrix[dof+fix+1];
00616 }
00617 catch(bad_alloc ex)
00618 {
00619 cerr << "Robot_basic constructor : new ran out of memory" << endl;
00620 exit(1);
00621 }
00622
00623 for(i = 0; i <= dof; i++)
00624 {
00625 w[i] = ColumnVector(3);
00626 w[i] = 0.0;
00627 wp[i] = ColumnVector(3);
00628 wp[i] = 0.0;
00629 vp[i] = ColumnVector(3);
00630 dw[i] = ColumnVector(3);
00631 dw[i] = 0.0;
00632 dwp[i] = ColumnVector(3);
00633 dwp[i] = 0.0;
00634 dvp[i] = ColumnVector(3);
00635 dvp[i] = 0.0;
00636 }
00637 for(i = 0; i <= dof+fix; i++)
00638 {
00639 R[i] = Matrix(3,3);
00640 R[i] << threebythreeident;
00641 p[i] = ColumnVector(3);
00642 p[i] = 0.0;
00643 pp[i] = p[i];
00644 }
00645
00646 if ( initrobot.Nrows() == initmotor.Nrows() )
00647 {
00648 if(initmotor.Ncols() == 4)
00649 {
00650 switch(initrobot.Ncols()){
00651 case 15:
00652 for(i = 1; i <= dof+fix; i++)
00653 {
00654 links[i] = Link((int) initrobot(i,1), initrobot(i,2), initrobot(i,3),
00655 initrobot(i,4), initrobot(i,5), 0, 0, 0, initrobot(i,6),
00656 initrobot(i,7), initrobot(i,8), initrobot(i,9),
00657 initrobot(i,10),initrobot(i,11), initrobot(i,12),
00658 initrobot(i,13),initrobot(i,14), initrobot(i,15),
00659 initmotor(i,1), initmotor(i,2), initmotor(i,3),
00660 initmotor(i,4), dh_parameter, min_inertial_para);
00661 }
00662 break;
00663 case 18:
00664 for(i = 1; i <= dof+fix; i++)
00665 {
00666 links[i] = Link((int) initrobot(i,1), initrobot(i,2), initrobot(i,3),
00667 initrobot(i,4), initrobot(i,5), initrobot(i,6),
00668 initrobot(i,7), initrobot(i,8), initrobot(i,9),
00669 initrobot(i,10),initrobot(i,11), initrobot(i,12),
00670 initrobot(i,13),initrobot(i,14), initrobot(i,15),
00671 initrobot(i,16),initrobot(i,17), initrobot(i,18),
00672 initmotor(i,1), initmotor(i,2), initmotor(i,3),
00673 initmotor(i,4), dh_parameter, min_inertial_para);
00674 }
00675 break;
00676 default:
00677 error("Initialisation robot Matrix does not have 16 or 18 columns.");
00678 }
00679 }
00680 else
00681 error("Initialisation robot motor Matrix does not have 4 columns.");
00682
00683 }
00684 else
00685 error("Initialisation robot and motor matrix does not have same numbers of Rows.");
00686 }
00687
00688 Robot_basic::Robot_basic(const int ndof, const bool ,
00689 const bool )
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699 : w(NULL), wp(NULL), vp(NULL), a(NULL), f(NULL), f_nv(NULL), n(NULL), n_nv(NULL),
00700 F(NULL), N(NULL), p(NULL), pp(NULL), dw(NULL), dwp(NULL), dvp(NULL), da(NULL),
00701 df(NULL), dn(NULL), dF(NULL), dN(NULL), dp(NULL), z0(3), gravity(3), R(NULL),
00702 links(NULL), robotType(DEFAULT), dof(ndof), fix(0)
00703 {
00704 int i = 0;
00705 gravity = 0.0;
00706 gravity(3) = 9.81;
00707 z0(1) = z0(2) = 0.0; z0(3) = 1.0;
00708
00709 try
00710 {
00711 links = new Link[dof];
00712 links = links-1;
00713 w = new ColumnVector[dof+1];
00714 wp = new ColumnVector[dof+1];
00715 vp = new ColumnVector[dof+1];
00716 a = new ColumnVector[dof+1];
00717 f = new ColumnVector[dof+1];
00718 f_nv = new ColumnVector[dof+1];
00719 n = new ColumnVector[dof+1];
00720 n_nv = new ColumnVector[dof+1];
00721 F = new ColumnVector[dof+1];
00722 N = new ColumnVector[dof+1];
00723 p = new ColumnVector[dof+1];
00724 pp = new ColumnVector[dof+fix+1];
00725 dw = new ColumnVector[dof+1];
00726 dwp = new ColumnVector[dof+1];
00727 dvp = new ColumnVector[dof+1];
00728 da = new ColumnVector[dof+1];
00729 df = new ColumnVector[dof+1];
00730 dn = new ColumnVector[