$search
00001 /* 00002 ROBOOP -- A robotics object oriented package in C++ 00003 Copyright (C) 1996-2004 Richard Gourdeau 00004 00005 This library is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU Lesser General Public License as 00007 published by the Free Software Foundation; either version 2.1 of the 00008 License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU Lesser General Public License for more details. 00014 00015 You should have received a copy of the GNU Lesser General Public 00016 License along with this library; if not, write to the Free Software 00017 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 00019 00020 Report problems and direct all questions to: 00021 00022 Richard Gourdeau 00023 Professeur Agrege 00024 Departement de genie electrique 00025 Ecole Polytechnique de Montreal 00026 C.P. 6079, Succ. Centre-Ville 00027 Montreal, Quebec, H3C 3A7 00028 00029 email: richard.gourdeau@polymtl.ca 00030 ------------------------------------------------------------------------------- 00031 Revision_history: 00032 00033 2003/02/03: Etienne Lachance 00034 -Rewrite mRobot::jacobian() since previous version was incorrect. 00035 -Added functions kine_pd(). 00036 -Make sur that joint angles (qout) are in [-pi, pi] in inv_kin functions. 00037 00038 2003/05/18: Etienne Lachance 00039 -Added functions Robot_basic::jacobian_DLS_inv and 00040 Robot/mRobot/mRobot_min_para::jacobian_dot 00041 00042 2003/08/22: Etienne Lachance 00043 -Added parameter converge in inv_kin prototype function. It indicates if the 00044 inverse kinematics solution converge. 00045 00046 2003/11/26: Etienne Lachance 00047 -Use angle conditions only if it converge in inv_kin. 00048 00049 2004/01/23: Etienne Lachance 00050 -Added const in non reference argument for all functions. 00051 00052 2004/03/12: Etienne Lachance 00053 -Added logic to set q in inv_kin. 00054 00055 2004/04/24: Etienne Lachance 00056 -Moved inv_kin to invkine.cpp. 00057 00058 2004/05/14: Etienne Lachance 00059 -Replaced vec_x_prod by CrossProduct. 00060 00061 2004/05/21: Etienne Lachance 00062 -Added Doxygen comments. 00063 00064 2004/07/01: Ethan Tira-Thompson 00065 -Added support for newmat's use_namespace #define, using ROBOOP namespace 00066 00067 2004/07/16: Ethan Tira-Thompson 00068 -Supports Link::immobile flag so jacobians and deltas are 0 for immobile joints 00069 -Jacobians will only contain entries for mobile joints - otherwise NaNs result 00070 in later processing 00071 -Added parameters to jacobian functions to generate for frames other than 00072 the end effector 00073 ------------------------------------------------------------------------------- 00074 */ 00075 00081 00082 static const char rcsid[] = "$Id: kinemat.cpp,v 1.31 2004/08/16 00:37:53 gourdeau Exp $"; 00083 00084 #include "robot.h" 00085 00086 #ifdef use_namespace 00087 namespace ROBOOP { 00088 using namespace NEWMAT; 00089 #endif 00090 00091 00092 void Robot_basic::kine(Matrix & Rot, ColumnVector & pos)const 00098 { 00099 kine(Rot,pos,dof+fix); 00100 } 00101 00102 void Robot_basic::kine(Matrix & Rot, ColumnVector & pos, const int j)const 00109 { 00110 if(j < 1 || j > dof+fix) error("j must be 1 <= j <= dof+fix"); 00111 00112 Rot = links[1].R; 00113 pos = links[1].p; 00114 for (int i = 2; i <= j; i++) { 00115 pos = pos + Rot*links[i].p; 00116 Rot = Rot*links[i].R; 00117 } 00118 } 00119 00120 ReturnMatrix Robot_basic::kine(void)const 00122 { 00123 Matrix thomo; 00124 00125 thomo = kine(dof+fix); 00126 thomo.Release(); return thomo; 00127 } 00128 00129 ReturnMatrix Robot_basic::kine(const int j)const 00131 { 00132 Matrix Rot, thomo(4,4); 00133 ColumnVector pos; 00134 00135 kine(Rot,pos,j); 00136 thomo << fourbyfourident; 00137 thomo.SubMatrix(1,3,1,3) = Rot; 00138 thomo.SubMatrix(1,3,4,4) = pos; 00139 thomo.Release(); return thomo; 00140 } 00141 00142 ReturnMatrix Robot_basic::kine_pd(const int j)const 00153 { 00154 Matrix temp(3,5), Rot; 00155 ColumnVector pos, pos_dot; 00156 00157 if(j < 1 || j > dof) 00158 error("j must be 1 <= j <= dof"); 00159 00160 kine_pd(Rot, pos, pos_dot, j); 00161 00162 temp.SubMatrix(1,3,1,3) = Rot; 00163 temp.SubMatrix(1,3,4,4) = pos; 00164 temp.SubMatrix(1,3,5,5) = pos_dot; 00165 temp.Release(); 00166 return temp; 00167 } 00168 00169 ReturnMatrix Robot_basic::jacobian_DLS_inv(const double eps, const double lambda_max, 00170 const int ref)const 00200 { 00201 Matrix jacob_inv_DLS, U, V; 00202 DiagonalMatrix Q; 00203 SVD(jacobian(ref), Q, U, V); 00204 00205 if(Q(6,6) >= eps) 00206 jacob_inv_DLS = V*Q.i()*U.t(); 00207 else 00208 { 00209 Q(6,6) += (1 - pow(Q(6,6)/eps,2))*lambda_max*lambda_max; 00210 jacob_inv_DLS = V*Q.i()*U.t(); 00211 } 00212 00213 jacob_inv_DLS.Release(); 00214 return(jacob_inv_DLS); 00215 } 00216 00217 // --------------------- R O B O T DH N O T A T I O N -------------------------- 00218 00219 void Robot::kine_pd(Matrix & Rot, ColumnVector & pos, ColumnVector & pos_dot, 00220 const int j)const 00229 { 00230 if(j < 1 || j > dof) 00231 error("j must be 1 <= j <= dof"); 00232 00233 if( (pos.Nrows()!=3) || (pos.Ncols()!=1) ) 00234 pos = ColumnVector(3); 00235 if( (pos_dot.Nrows()!=3) || (pos_dot.Ncols()!=1) ) 00236 pos_dot = ColumnVector(3); 00237 00238 pos = 0.0; 00239 pos_dot = 0.0; 00240 for(int i = 1; i <= j; i++) 00241 { 00242 R[i] = R[i-1]*links[i].R; 00243 pos = pos + R[i-1]*links[i].p; 00244 pos_dot = pos_dot + CrossProduct(R[i]*w[i], R[i-1]*links[i].p); 00245 } 00246 Rot = R[j]; 00247 } 00248 00249 void Robot::dTdqi(Matrix & dRot, ColumnVector & dp, 00250 const int i) 00293 { 00294 int j; 00295 if(i < 1 || i > dof) error("i must be 1 <= i <= dof"); 00296 if(links[i].get_immobile()) { 00297 dRot = Matrix(3,3); 00298 dp = Matrix(3,1); 00299 dRot = 0.0; 00300 dp = 0.0; 00301 } else if(links[i].get_joint_type() == 0) { 00302 Matrix dR(3,3); 00303 dR = 0.0; 00304 Matrix R2 = links[i].R; 00305 ColumnVector p2 = links[i].p; 00306 dRot = Matrix(3,3); 00307 dRot << threebythreeident; 00308 for(j = 1; j < i; j++) { 00309 dRot = dRot*links[j].R; 00310 } 00311 // dRot * Q 00312 for(j = 1; j <= 3; j++) { 00313 dR(j,1) = dRot(j,2); 00314 dR(j,2) = -dRot(j,1); 00315 } 00316 for(j = i+1; j <= dof; j++) { 00317 p2 = p2 + R2*links[j].p; 00318 R2 = R2*links[j].R; 00319 } 00320 dp = dR*p2; 00321 dRot = dR*R2; 00322 } else { 00323 dRot = Matrix(3,3); 00324 dp = Matrix(3,1); 00325 dRot = 0.0; 00326 dp = 0.0; 00327 dp(3) = 1.0; 00328 for(j = i-1; j >= 1; j--) { 00329 dp = links[j].R*dp; 00330 } 00331 } 00332 } 00333 00334 ReturnMatrix Robot::dTdqi(const int i) 00341 { 00342 Matrix dRot, thomo(4,4); 00343 ColumnVector dpos; 00344 00345 dTdqi(dRot, dpos, i); 00346 thomo = (Real) 0.0; 00347 thomo.SubMatrix(1,3,1,3) = dRot; 00348 thomo.SubMatrix(1,3,4,4) = dpos; 00349 thomo.Release(); return thomo; 00350 } 00351 00352 ReturnMatrix Robot::jacobian(const int endlink, const int ref)const 00401 { 00402 int i, j; 00403 const int adof=get_available_dof(endlink); 00404 Matrix jac(6,adof); 00405 Matrix pr, temp(3,1); 00406 00407 if(ref < 0 || ref > dof) error("invalid referential"); 00408 00409 for(i = 1; i <= dof; i++) { 00410 R[i] = R[i-1]*links[i].R; 00411 p[i] = p[i-1]+R[i-1]*links[i].p; 00412 } 00413 00414 for(i=1,j=1; j <= adof; i++) { 00415 if(links[i].get_immobile()) 00416 continue; 00417 if(links[i].get_joint_type() == 0) { 00418 temp(1,1) = R[i-1](1,3); 00419 temp(2,1) = R[i-1](2,3); 00420 temp(3,1) = R[i-1](3,3); 00421 pr = p[dof]-p[i-1]; 00422 temp = CrossProduct(temp,pr); 00423 jac(1,j) = temp(1,1); 00424 jac(2,j) = temp(2,1); 00425 jac(3,j) = temp(3,1); 00426 jac(4,j) = R[i-1](1,3); 00427 jac(5,j) = R[i-1](2,3); 00428 jac(6,j) = R[i-1](3,3); 00429 } else { 00430 jac(1,j) = R[i-1](1,3); 00431 jac(2,j) = R[i-1](2,3); 00432 jac(3,j) = R[i-1](3,3); 00433 jac(4,j) = jac(5,j) = jac(6,j) = 0.0; 00434 } 00435 j++; 00436 } 00437 00438 if(ref != 0) { 00439 Matrix zeros(3,3); 00440 zeros = (Real) 0.0; 00441 Matrix RT = R[ref].t(); 00442 Matrix Rot; 00443 Rot = ((RT & zeros) | (zeros & RT)); 00444 jac = Rot*jac; 00445 } 00446 jac.Release(); return jac; 00447 } 00448 00449 ReturnMatrix Robot::jacobian_dot(const int ref)const 00497 { 00498 int i, j; 00499 const int adof=get_available_dof(); 00500 Matrix jacdot(6,adof); 00501 ColumnVector e(3), temp, pr, ppr; 00502 00503 if(ref < 0 || ref > dof) 00504 error("invalid referential"); 00505 00506 for(i = 1; i <= dof; i++) 00507 { 00508 R[i] = R[i-1]*links[i].R; 00509 p[i] = p[i-1] + R[i-1]*links[i].p; 00510 pp[i] = pp[i-1] + CrossProduct(R[i]*w[i], R[i-1]*links[i].p); 00511 } 00512 00513 for(i=1,j=1; j <= adof; i++) { 00514 if(links[i].get_immobile()) 00515 continue; 00516 if(links[i].get_joint_type() == 0) 00517 { 00518 pr = p[dof]-p[i-1]; 00519 ppr = pp[dof]-pp[i-1]; 00520 e(1) = R[i-1](1,3); 00521 e(2) = R[i-1](2,3); 00522 e(3) = R[i-1](3,3); 00523 temp = CrossProduct(R[i-1]*w[i-1], e); 00524 jacdot(4,j) = temp(1); // d(e)/dt 00525 jacdot(5,j) = temp(2); 00526 jacdot(6,j) = temp(3); 00527 temp = CrossProduct(temp,pr) + CrossProduct(e,ppr); 00528 jacdot(1,j) = temp(1); 00529 jacdot(2,j) = temp(2); 00530 jacdot(3,j) = temp(3); 00531 } 00532 else 00533 jacdot(1,j) = jacdot(2,j) = jacdot(3,j) = 00534 jacdot(4,j) = jacdot(5,j) = jacdot(6,j) = 0.0; 00535 j++; 00536 } 00537 00538 if(ref != 0) { 00539 Matrix zeros(3,3); 00540 zeros = (Real) 0.0; 00541 Matrix RT = R[ref].t(); 00542 Matrix Rot; 00543 Rot = ((RT & zeros) | (zeros & RT)); 00544 jacdot = Rot*jacdot; 00545 } 00546 00547 jacdot.Release(); return jacdot; 00548 } 00549 00550 // ---------------- R O B O T M O D I F I E D DH N O T A T I O N -------------------------- 00551 00552 void mRobot::kine_pd(Matrix & Rot, ColumnVector & pos, ColumnVector & pos_dot, 00553 const int j)const 00562 { 00563 if(j < 1 || j > dof+fix) 00564 error("j must be 1 <= j <= dof+fix"); 00565 00566 if( (pos.Nrows()!=3) || (pos.Ncols()!=1) ) 00567 pos = ColumnVector(3); 00568 if( (pos_dot.Nrows()!=3) || (pos_dot.Ncols()!=1) ) 00569 pos_dot = ColumnVector(3); 00570 00571 pos = 0.0; 00572 pos_dot = 0.0; 00573 for(int i = 1; i <= j; i++) 00574 { 00575 pos = pos + R[i-1]*links[i].p; 00576 pos_dot = pos_dot + R[i-1]*CrossProduct(w[i-1], links[i].p); 00577 R[i] = R[i-1]*links[i].R; 00578 } 00579 Rot = R[j]; 00580 } 00581 00582 void mRobot::dTdqi(Matrix & dRot, ColumnVector & dp, const int i) 00618 { 00619 int j; 00620 if(i < 1 || i > dof) error("i must be 1 <= i <= dof"); 00621 if(links[i].get_immobile()) { 00622 dRot = Matrix(3,3); 00623 dp = Matrix(3,1); 00624 dRot = 0.0; 00625 dp = 0.0; 00626 } else if(links[i].get_joint_type() == 0) { 00627 Matrix dR(3,3), R2(3,3), p2(3,1); 00628 dR = 0.0; 00629 dRot = Matrix(3,3); 00630 dRot << threebythreeident; 00631 for(j = 1; j <= i; j++) { 00632 dRot = dRot*links[j].R; 00633 } 00634 // dRot * Q 00635 for(j = 1; j <= 3; j++) { 00636 dR(j,1) = dRot(j,2); 00637 dR(j,2) = -dRot(j,1); 00638 } 00639 if(i < dof) { 00640 R2 = links[i+1].R; 00641 p2 = links[i+1].p; 00642 } else { 00643 R2 << threebythreeident; 00644 p2 = 0.0; 00645 } 00646 for(j = i+1; j <= dof; j++) { 00647 p2 = p2 + R2*links[j].p; 00648 R2 = R2*links[j].R; 00649 } 00650 dp = dR*p2; 00651 dRot = dR*R2; // probleme ... 00652 } else { 00653 dRot = Matrix(3,3); 00654 dp = Matrix(3,1); 00655 dRot = 0.0; 00656 dp = 0.0; 00657 dp(3) = 1.0; 00658 for(j = i; j >= 1; j--) { 00659 dp = links[j].R*dp; 00660 } 00661 } 00662 } 00663 00664 ReturnMatrix mRobot::dTdqi(const int i) 00671 { 00672 Matrix dRot, thomo(4,4); 00673 ColumnVector dpos; 00674 00675 dTdqi(dRot, dpos, i); 00676 thomo = (Real) 0.0; 00677 thomo.SubMatrix(1,3,1,3) = dRot; 00678 thomo.SubMatrix(1,3,4,4) = dpos; 00679 thomo.Release(); return thomo; 00680 } 00681 00682 ReturnMatrix mRobot::jacobian(const int endlink, const int ref)const 00688 { 00689 int i, j; 00690 const int adof=get_available_dof(endlink); 00691 Matrix jac(6,adof); 00692 ColumnVector pr(3), temp(3); 00693 00694 if(ref < 0 || ref > dof+fix) 00695 error("invalid referential"); 00696 00697 for(i = 1; i <= dof+fix; i++) { 00698 R[i] = R[i-1]*links[i].R; 00699 p[i] = p[i-1] + R[i-1]*links[i].p; 00700 } 00701 00702 for(i=1,j=1; j <= adof; i++) { 00703 if(links[i].get_immobile()) 00704 continue; 00705 if(links[i].get_joint_type() == 0){ 00706 temp(1) = R[i](1,3); 00707 temp(2) = R[i](2,3); 00708 temp(3) = R[i](3,3); 00709 pr = p[dof+fix]-p[i]; 00710 temp = CrossProduct(temp,pr); 00711 jac(1,j) = temp(1); 00712 jac(2,j) = temp(2); 00713 jac(3,j) = temp(3); 00714 jac(4,j) = R[i](1,3); 00715 jac(5,j) = R[i](2,3); 00716 jac(6,j) = R[i](3,3); 00717 } else { 00718 jac(1,j) = R[i](1,3); 00719 jac(2,j) = R[i](2,3); 00720 jac(3,j) = R[i](3,3); 00721 jac(4,j) = jac(5,j) = jac(6,j) = 0.0; 00722 } 00723 j++; 00724 } 00725 if(ref != 0) { 00726 Matrix zeros(3,3); 00727 zeros = (Real) 0.0; 00728 Matrix RT = R[ref].t(); 00729 Matrix Rot; 00730 Rot = ((RT & zeros) | (zeros & RT)); 00731 jac = Rot*jac; 00732 } 00733 jac.Release(); return jac; 00734 } 00735 00736 ReturnMatrix mRobot::jacobian_dot(const int ref)const 00742 { 00743 int i, j; 00744 const int adof=get_available_dof(); 00745 Matrix jacdot(6,adof); 00746 ColumnVector e(3), temp, pr, ppr; 00747 00748 if(ref < 0 || ref > dof+fix) 00749 error("invalid referential"); 00750 00751 for(i = 1; i <= dof+fix; i++) 00752 { 00753 R[i] = R[i-1]*links[i].R; 00754 p[i] = p[i-1] + R[i-1]*links[i].p; 00755 pp[i] = pp[i-1] + R[i-1]*CrossProduct(w[i-1], links[i].p); 00756 } 00757 00758 for(i=1,j=1; j <= adof; i++) { 00759 if(links[i].get_immobile()) 00760 continue; 00761 if(links[i].get_joint_type() == 0) 00762 { 00763 pr = p[dof+fix]-p[i]; 00764 ppr = pp[dof+fix]-pp[i]; 00765 00766 e(1) = R[i](1,3); 00767 e(2) = R[i](2,3); 00768 e(3) = R[i](3,3); 00769 temp = CrossProduct(R[i-1]*w[i-1], e); 00770 jacdot(4,j) = temp(1); // d(e)/dt 00771 jacdot(5,j) = temp(2); 00772 jacdot(6,j) = temp(3); 00773 00774 temp = CrossProduct(temp,pr) + CrossProduct(e,ppr); 00775 jacdot(1,j) = temp(1); 00776 jacdot(2,j) = temp(2); 00777 jacdot(3,j) = temp(3); 00778 } 00779 else 00780 jacdot(1,j) = jacdot(2,j) = jacdot(3,j) = 00781 jacdot(4,j) = jacdot(5,j) = jacdot(6,j) = 0.0; 00782 j++; 00783 } 00784 00785 if(ref != 0) { 00786 Matrix zeros(3,3); 00787 zeros = (Real) 0.0; 00788 Matrix RT = R[ref].t(); 00789 Matrix Rot; 00790 Rot = ((RT & zeros) | (zeros & RT)); 00791 jacdot = Rot*jacdot; 00792 } 00793 00794 jacdot.Release(); return jacdot; 00795 } 00796 00797 // ------------- R O B O T DH M O D I F I E D, M I N I M U M P A R A M E T E R S ------------ 00798 00799 void mRobot_min_para::kine_pd(Matrix & Rot, ColumnVector & pos, ColumnVector & pos_dot, 00800 const int j)const 00809 { 00810 if(j < 1 || j > dof+fix) 00811 error("j must be 1 <= j <= dof+fix"); 00812 00813 if( (pos.Nrows()!=3) || (pos.Ncols()!=1) ) 00814 pos = ColumnVector(3); 00815 if( (pos_dot.Nrows()!=3) || (pos_dot.Ncols()!=1) ) 00816 pos_dot = ColumnVector(3); 00817 00818 pos = 0.0; 00819 pos_dot = 0.0; 00820 for(int i = 1; i <= j; i++) 00821 { 00822 pos = pos + R[i-1]*links[i].p; 00823 pos_dot = pos_dot + R[i-1]*CrossProduct(w[i-1], links[i].p); 00824 R[i] = R[i-1]*links[i].R; 00825 } 00826 Rot = R[j]; 00827 } 00828 00829 void mRobot_min_para::dTdqi(Matrix & dRot, ColumnVector & dp, const int i) 00841 { 00842 int j; 00843 if(i < 1 || i > dof) error("i must be 1 <= i <= dof"); 00844 if(links[i].get_immobile()) { 00845 dRot = Matrix(3,3); 00846 dp = Matrix(3,1); 00847 dRot = 0.0; 00848 dp = 0.0; 00849 } else if(links[i].get_joint_type() == 0) { 00850 Matrix dR(3,3), R2, p2(3,1); 00851 dR = 0.0; 00852 dRot = Matrix(3,3); 00853 dRot << threebythreeident; 00854 for(j = 1; j <= i; j++) { 00855 dRot = dRot*links[j].R; 00856 } 00857 // dRot * Q 00858 for(j = 1; j <= 3; j++) { 00859 dR(j,1) = dRot(j,2); 00860 dR(j,2) = -dRot(j,1); 00861 } 00862 if(i < dof) { 00863 R2 = links[i+1].R; 00864 p2 = links[i+1].p; 00865 } else { 00866 R2 << threebythreeident; 00867 p2 = 0.0; 00868 } 00869 for(j = i+1; j <= dof; j++) { 00870 p2 = p2 + R2*links[j].p; 00871 R2 = R2*links[j].R; 00872 } 00873 dp = dR*p2; 00874 dRot = dR*R2; 00875 } else { 00876 dRot = Matrix(3,3); 00877 dp = Matrix(3,1); 00878 dRot = 0.0; 00879 dp = 0.0; 00880 dp(3) = 1.0; 00881 for(j = i; j >= 1; j--) { 00882 dp = links[j].R*dp; 00883 } 00884 } 00885 } 00886 00887 ReturnMatrix mRobot_min_para::dTdqi(const int i) 00894 { 00895 Matrix dRot, thomo(4,4); 00896 ColumnVector dpos; 00897 00898 dTdqi(dRot, dpos, i); 00899 thomo = (Real) 0.0; 00900 thomo.SubMatrix(1,3,1,3) = dRot; 00901 thomo.SubMatrix(1,3,4,4) = dpos; 00902 thomo.Release(); return thomo; 00903 } 00904 00905 ReturnMatrix mRobot_min_para::jacobian(const int endlink, const int ref)const 00911 { 00912 int i, j; 00913 const int adof=get_available_dof(endlink); 00914 Matrix jac(6,adof); 00915 ColumnVector pr(3), temp(3); 00916 00917 if(ref < 0 || ref > dof+fix) 00918 error("invalid referential"); 00919 00920 for(i = 1; i <= dof+fix; i++) { 00921 R[i] = R[i-1]*links[i].R; 00922 p[i] = p[i-1] + R[i-1]*links[i].p; 00923 } 00924 00925 for(i=1,j=1; j<=adof; i++) { 00926 if(links[i].get_immobile()) 00927 continue; 00928 if(links[i].get_joint_type() == 0){ 00929 temp(1) = R[i](1,3); 00930 temp(2) = R[i](2,3); 00931 temp(3) = R[i](3,3); 00932 00933 pr = p[dof+fix]-p[i]; 00934 temp = CrossProduct(temp,pr); 00935 jac(1,j) = temp(1); 00936 jac(2,j) = temp(2); 00937 jac(3,j) = temp(3); 00938 jac(4,j) = R[i](1,3); 00939 jac(5,j) = R[i](2,3); 00940 jac(6,j) = R[i](3,3); 00941 } else { 00942 jac(1,j) = R[i](1,3); 00943 jac(2,j) = R[i](2,3); 00944 jac(3,j) = R[i](3,3); 00945 jac(4,j) = jac(5,j) = jac(6,j) = 0.0; 00946 } 00947 j++; 00948 } 00949 if(ref != 0) { 00950 Matrix zeros(3,3); 00951 zeros = (Real) 0.0; 00952 Matrix RT = R[ref].t(); 00953 Matrix Rot; 00954 Rot = ((RT & zeros) | (zeros & RT)); 00955 jac = Rot*jac; 00956 } 00957 00958 jac.Release(); return jac; 00959 } 00960 00961 ReturnMatrix mRobot_min_para::jacobian_dot(const int ref)const 00967 { 00968 int i, j; 00969 const int adof=get_available_dof(); 00970 Matrix jacdot(6,adof); 00971 ColumnVector e(3), temp, pr, ppr; 00972 00973 if(ref < 0 || ref > dof+fix) 00974 error("invalid referential"); 00975 00976 for(i = 1; i <= dof+fix; i++) 00977 { 00978 R[i] = R[i-1]*links[i].R; 00979 p[i] = p[i-1] + R[i-1]*links[i].p; 00980 pp[i] = pp[i-1] + R[i-1]*CrossProduct(w[i-1], links[i].p); 00981 } 00982 00983 for(i=1,j=1; j <= dof; i++) { 00984 if(links[i].get_immobile()) 00985 continue; 00986 if(links[i].get_joint_type() == 0) 00987 { 00988 pr = p[dof+fix]-p[i]; 00989 ppr = pp[dof+fix]-pp[i]; 00990 00991 e(1) = R[i](1,3); 00992 e(2) = R[i](2,3); 00993 e(3) = R[i](3,3); 00994 temp = CrossProduct(R[i-1]*w[i-1], e); 00995 jacdot(4,j) = temp(1); // d(e)/dt 00996 jacdot(5,j) = temp(2); 00997 jacdot(6,j) = temp(3); 00998 00999 temp = CrossProduct(temp,pr) + CrossProduct(e,ppr); 01000 jacdot(1,j) = temp(1); 01001 jacdot(2,j) = temp(2); 01002 jacdot(3,j) = temp(3); 01003 } 01004 else 01005 jacdot(1,j) = jacdot(2,j) = jacdot(3,j) = 01006 jacdot(4,j) = jacdot(5,j) = jacdot(6,j) = 0.0; 01007 j++; 01008 } 01009 01010 if(ref != 0) { 01011 Matrix zeros(3,3); 01012 zeros = (Real) 0.0; 01013 Matrix RT = R[ref].t(); 01014 Matrix Rot; 01015 Rot = ((RT & zeros) | (zeros & RT)); 01016 jacdot = Rot*jacdot; 01017 } 01018 01019 jacdot.Release(); return jacdot; 01020 } 01021 01022 #ifdef use_namespace 01023 } 01024 #endif