52 #include <visp/vpDebug.h>
53 #include <visp/vpVelocityTwistMatrix.h>
54 #include <visp/vpRobotException.h>
55 #include <visp/vpCameraParameters.h>
56 #include <visp/vpRxyzVector.h>
57 #include <visp/vpTranslationVector.h>
58 #include <visp/vpRotationMatrix.h>
59 #include <visp/vpViper.h>
71 : eMc(), etc(), erc(), a1(0), d1(0), a2(), a3(), d4(0), d6(0), c56(0), joint_max(), joint_min()
82 c56 = -341.33 / 9102.22;
152 vpViper::convertJointPositionInLimits(
unsigned int joint,
const double &q,
double &q_mod,
const bool &verbose)
const
171 std::cout <<
"Joint " << joint <<
" not in limits: "
172 << this->
joint_min[joint] <<
" < " << q <<
" < " << this->
joint_max[joint] << std::endl;
236 for (
unsigned int i=0; i<8; i++)
239 double c1[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
240 double s1[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
241 double c3[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
242 double s3[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
243 double c23[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
244 double s23[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
245 double c4[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
246 double s4[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
247 double c5[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
248 double s5[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
249 double c6[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
250 double s6[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
257 for (
unsigned int i=0; i< 8; i++)
260 double px = fMw[0][3];
261 double py = fMw[1][3];
262 double pz = fMw[2][3];
265 double a_2 = px*px+py*py;
267 if (std::fabs(a_2) <= std::numeric_limits<double>::epsilon()) {
270 c1[4] = cos(q[0]+M_PI);
271 s1[4] = sin(q[0]+M_PI);
274 double a = sqrt(a_2);
282 for(
unsigned int i=0;i<8;i+=4) {
283 q_sol[i][0] = atan2(s1[i],c1[i]);
284 if (convertJointPositionInLimits(0, q_sol[i][0], q1_mod, verbose) ==
true) {
285 q_sol[i][0] = q1_mod;
286 for(
unsigned int j=1;j<4;j++) {
289 q_sol[i+j][0] = q_sol[i][0];
293 for(
unsigned int j=1;j<4;j++)
300 for(
unsigned int i=0; i<8; i+=4) {
303 - 2*(
a1*c1[i]*px +
a1*s1[i]*py +
d1*pz)) / (2*
a2);
306 q_sol[i][2] = atan2(
a3,
d4) + atan2(K, sqrt(d4_a3_K));
307 q_sol[i+2][2] = atan2(
a3,
d4) + atan2(K, -sqrt(d4_a3_K));
309 for (
unsigned int j=0; j<4; j+=2) {
311 for(
unsigned int k=0; k<2; k++)
315 if (convertJointPositionInLimits(2, q_sol[i+j][2], q3_mod, verbose) ==
true) {
316 for(
unsigned int k=0; k<2; k++) {
317 q_sol[i+j+k][2] = q3_mod;
318 c3[i+j+k] = cos(q3_mod);
319 s3[i+j+k] = sin(q3_mod);
323 for(
unsigned int k=0; k<2; k++)
336 double q23[8], q2_mod;
337 for (
unsigned int i=0; i<8; i+=2) {
340 c23[i] = (-(
a3-
a2*c3[i])*(c1[i]*px+s1[i]*py-
a1)-(
d1-pz)*(
d4+
a2*s3[i]))
341 / ( (c1[i]*px+s1[i]*py-
a1)*(c1[i]*px+s1[i]*py-
a1) +(
d1-pz)*(
d1-pz) );
342 s23[i] = ((
d4+
a2*s3[i])*(c1[i]*px+s1[i]*py-
a1)-(
d1-pz)*(
a3-
a2*c3[i]))
343 / ( (c1[i]*px+s1[i]*py-
a1)*(c1[i]*px+s1[i]*py-
a1) +(
d1-pz)*(
d1-pz) );
344 q23[i] = atan2(s23[i],c23[i]);
347 q_sol[i][1] = q23[i] - q_sol[i][2];
349 if (convertJointPositionInLimits(1, q_sol[i][1], q2_mod, verbose) ==
true) {
350 for(
unsigned int j=0; j<2; j++) {
351 q_sol[i+j][1] = q2_mod;
357 for(
unsigned int j=0; j<2; j++)
368 double r13 = fMw[0][2];
369 double r23 = fMw[1][2];
370 double r33 = fMw[2][2];
371 double s4s5, c4s5, q4_mod, q5_mod;
372 for (
unsigned int i=0; i<8; i+=2) {
374 s4s5 = -s1[i]*r13+c1[i]*r23;
375 c4s5 = c1[i]*c23[i]*r13+s1[i]*c23[i]*r23-s23[i]*r33;
378 c5[i] = c1[i]*s23[i]*r13+s1[i]*s23[i]*r23+c23[i]*r33;
385 if (convertJointPositionInLimits(4, q_sol[i][4], q5_mod, verbose) ==
true) {
386 for(
unsigned int j=0; j<2; j++) {
387 q_sol[i+j][3] = q[3];
388 q_sol[i+j][4] = q5_mod;
389 c4[i] = cos(q_sol[i+j][3]);
390 s4[i] = sin(q_sol[i+j][3]);
394 for(
unsigned int j=0; j<2; j++)
401 if (std::fabs(c4s5) <= std::numeric_limits<double>::epsilon()) {
405 q_sol[i][3] = atan2(s4s5, c4s5);
408 q_sol[i][3] = atan2(s4s5, c4s5);
410 if (convertJointPositionInLimits(3, q_sol[i][3], q4_mod, verbose) ==
true) {
411 q_sol[i][3] = q4_mod;
418 if (q_sol[i][3] > 0.)
419 q_sol[i+1][3] = q_sol[i][3] + M_PI;
421 q_sol[i+1][3] = q_sol[i][3] - M_PI;
422 if (convertJointPositionInLimits(3, q_sol[i+1][3], q4_mod, verbose) ==
true) {
423 q_sol[i+1][3] = q4_mod;
424 c4[i+1] = cos(q4_mod);
425 s4[i+1] = sin(q4_mod);
432 for (
unsigned int j=0; j<2; j++) {
433 if (ok[i+j] ==
true) {
434 c5[i+j] = c1[i+j]*s23[i+j]*r13+s1[i+j]*s23[i+j]*r23+c23[i+j]*r33;
435 s5[i+j] = (c1[i+j]*c23[i+j]*c4[i+j]-s1[i+j]*s4[i+j])*r13
436 +(s1[i+j]*c23[i+j]*c4[i+j]+c1[i+j]*s4[i+j])*r23-s23[i+j]*c4[i+j]*r33;
438 q_sol[i+j][4] = atan2(s5[i+j], c5[i+j]);
439 if (convertJointPositionInLimits(4, q_sol[i+j][4], q5_mod, verbose) ==
true) {
440 q_sol[i+j][4] = q5_mod;
454 double r12 = fMw[0][1];
455 double r22 = fMw[1][1];
456 double r32 = fMw[2][1];
458 for (
unsigned int i=0; i<8; i++) {
459 c6[i] = -(c1[i]*c23[i]*s4[i]+s1[i]*c4[i])*r12
460 +(c1[i]*c4[i]-s1[i]*c23[i]*s4[i])*r22+s23[i]*s4[i]*r32;
461 s6[i] = -(c1[i]*c23[i]*c4[i]*c5[i]-c1[i]*s23[i]*s5[i]
462 -s1[i]*s4[i]*c5[i])*r12
463 -(s1[i]*c23[i]*c4[i]*c5[i]-s1[i]*s23[i]*s5[i]+c1[i]*s4[i]*c5[i])*r22
464 +(c23[i]*s5[i]+s23[i]*c4[i]*c5[i])*r32;
466 q_sol[i][5] = atan2(s6[i], c6[i]);
467 if (convertJointPositionInLimits(5, q_sol[i][5], q6_mod, verbose) ==
true) {
468 q_sol[i][5] = q6_mod;
476 unsigned int nbsol = 0;
477 unsigned int sol = 0;
479 for (
unsigned int i=0; i<8; i++) {
487 weight[1] = weight[2] = 4;
489 for (
unsigned int j=0; j< 6; j++) {
490 double rought_dist = q[j]- q_sol[i][j];
491 double modulo_dist = rought_dist;
492 if (rought_dist > 0) {
493 if (fabs(rought_dist - 2*M_PI) < fabs(rought_dist))
494 modulo_dist = rought_dist - 2*M_PI;
497 if (fabs(rought_dist + 2*M_PI) < fabs(rought_dist))
498 modulo_dist = rought_dist + 2*M_PI;
508 for (
unsigned int i=0; i<8; i++) {
510 if (dist[i] < dist[sol]) sol = i;
654 fMc = fMe * this->
eMc;
762 double c23 = cos(q2+q3);
763 double s23 = sin(q2+q3);
765 fMe[0][0] = c1*(c23*(c4*c5*c6-s4*s6)-s23*s5*c6)-s1*(s4*c5*c6+c4*s6);
766 fMe[1][0] = -s1*(c23*(-c4*c5*c6+s4*s6)+s23*s5*c6)+c1*(s4*c5*c6+c4*s6);
767 fMe[2][0] = s23*(s4*s6-c4*c5*c6)-c23*s5*c6;
769 fMe[0][1] = -c1*(c23*(c4*c5*s6+s4*c6)-s23*s5*s6)+s1*(s4*c5*s6-c4*c6);
770 fMe[1][1] = -s1*(c23*(c4*c5*s6+s4*c6)-s23*s5*s6)-c1*(s4*c5*s6-c4*c6);
771 fMe[2][1] = s23*(c4*c5*s6+s4*c6)+c23*s5*s6;
773 fMe[0][2] = c1*(c23*c4*s5+s23*c5)-s1*s4*s5;
774 fMe[1][2] = s1*(c23*c4*s5+s23*c5)+c1*s4*s5;
775 fMe[2][2] = -s23*c4*s5+c23*c5;
777 fMe[0][3] = c1*(c23*(c4*s5*
d6-
a3)+s23*(c5*
d6+
d4)+
a1+
a2*c2)-s1*s4*s5*
d6;
778 fMe[1][3] = s1*(c23*(c4*s5*
d6-
a3)+s23*(c5*
d6+
d4)+
a1+
a2*c2)+c1*s4*s5*
d6;
858 double c23 = cos(q2+q3);
859 double s23 = sin(q2+q3);
861 fMw[0][0] = c1*(c23*(c4*c5*c6-s4*s6)-s23*s5*c6)-s1*(s4*c5*c6+c4*s6);
862 fMw[1][0] = -s1*(c23*(-c4*c5*c6+s4*s6)+s23*s5*c6)+c1*(s4*c5*c6+c4*s6);
863 fMw[2][0] = s23*(s4*s6-c4*c5*c6)-c23*s5*c6;
865 fMw[0][1] = -c1*(c23*(c4*c5*s6+s4*c6)-s23*s5*s6)+s1*(s4*c5*s6-c4*c6);
866 fMw[1][1] = -s1*(c23*(c4*c5*s6+s4*c6)-s23*s5*s6)-c1*(s4*c5*s6-c4*c6);
867 fMw[2][1] = s23*(c4*c5*s6+s4*c6)+c23*s5*s6;
869 fMw[0][2] = c1*(c23*c4*s5+s23*c5)-s1*s4*s5;
870 fMw[1][2] = s1*(c23*c4*s5+s23*c5)+c1*s4*s5;
871 fMw[2][2] = -s23*c4*s5+c23*c5;
873 fMw[0][3] = c1*(-c23*
a3+s23*
d4+
a1+
a2*c2);
874 fMw[1][3] = s1*(-c23*
a3+s23*
d4+
a1+
a2*c2);
996 for (
unsigned int i=0; i<3; i++ ) {
997 for (
unsigned int j=0; j<3; j++ ) {
998 V[i][j] = V[i+3][j+3] = wRf[i][j];
1009 for (
unsigned int i=0; i<3; i++ ) {
1010 for (
unsigned int j=0; j<3; j++ ) {
1011 V[i][j+3] = block2[i][j];
1079 double c1 = cos(q1);
1080 double s1 = sin(q1);
1081 double c2 = cos(q2);
1082 double s2 = sin(q2);
1083 double c3 = cos(q3);
1084 double s3 = sin(q3);
1085 double c4 = cos(q4);
1086 double s4 = sin(q4);
1087 double c5 = cos(q5);
1088 double s5 = sin(q5);
1089 double c23 = cos(q2+q3);
1090 double s23 = sin(q2+q3);
1100 J1[0] = -s1*(-c23*
a3+s23*
d4+
a1+
a2*c2);
1101 J1[1] = c1*(-c23*
a3+s23*
d4+
a1+
a2*c2);
1107 J2[0] = c1*(s23*
a3+c23*
d4-
a2*s2);
1108 J2[1] = s1*(s23*
a3+c23*
d4-
a2*s2);
1109 J2[2] = c23*
a3-s23*
d4-
a2*c2;
1114 J3[0] = c1*(
a3*(s2*c3+c2*s3)+(-s2*s3+c2*c3)*
d4);
1115 J3[1] = s1*(
a3*(s2*c3+c2*s3)+(-s2*s3+c2*c3)*
d4);
1116 J3[2] = -
a3*(s2*s3-c2*c3)-
d4*(s2*c3+c2*s3);
1131 J5[3] = -c23*c1*s4-s1*c4;
1132 J5[4] = c1*c4-c23*s1*s4;
1138 J6[3] = (c1*c23*c4-s1*s4)*s5+c1*s23*c5;
1139 J6[4] = (s1*c23*c4+c1*s4)*s5+s1*s23*c5;
1140 J6[5] = -s23*c4*s5+c23*c5;
1143 for (
unsigned int i=0;i<6;i++) {
1182 for (
unsigned int i=0; i<6; i++ )
1196 vpMatrix block2 = (fRw*etw).skew();
1198 for (
unsigned int i=0; i<3; i++ )
1199 for (
unsigned int j=0; j<3; j++ )
1200 V[i][j+3] = block2[i][j];
1262 VISP_EXPORT std::ostream & operator << (std::ostream & os,
const vpViper & viper)
1275 <<
"Joint Max (deg):" << std::endl
1276 <<
"\t" << jmax.
t() << std::endl
1278 <<
"Joint Min (deg): " << std::endl
1279 <<
"\t" << jmin.
t() << std::endl
1281 <<
"Coupling 5-6:" << std::endl
1282 <<
"\t" << viper.
c56 << std::endl
1284 <<
"eMc: "<< std::endl
1285 <<
"\tTranslation (m): "
1286 << viper.
eMc[0][3] <<
" "
1287 << viper.
eMc[1][3] <<
" "
1289 <<
"\t" << std::endl
1290 <<
"\tRotation Rxyz (rad) : "
1294 <<
"\t" << std::endl
1295 <<
"\tRotation Rxyz (deg) : "
1299 <<
"\t" << std::endl;
void get_cVe(vpVelocityTwistMatrix &cVe) const
Definition of the vpMatrix class.
void get_eJe(const vpColVector &q, vpMatrix &eJe) const
void get_fMw(const vpColVector &q, vpHomogeneousMatrix &fMw) const
void resize(const unsigned int nrows, const unsigned int ncols, const bool nullify=true)
vpHomogeneousMatrix eMc
End effector to camera transformation.
vpRotationMatrix inverse() const
invert the rotation matrix
Modelisation of the ADEPT Viper robot.
double getCoupl56() const
unsigned int getInverseKinematicsWrist(const vpHomogeneousMatrix &fMw, vpColVector &q, const bool &verbose=false) const
void get_wMe(vpHomogeneousMatrix &wMe) const
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
void setIdentity()
Basic initialisation (identity)
void get_eMc(vpHomogeneousMatrix &eMc) const
The vpRotationMatrix considers the particular case of a rotation matrix.
double c56
Mechanical coupling between joint 5 and joint 6.
vpVelocityTwistMatrix buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
static double sqr(double x)
vpRowVector t() const
Transpose of a vector.
void extract(vpRotationMatrix &R) const
vpHomogeneousMatrix get_fMc(const vpColVector &q) const
void get_fMe(const vpColVector &q, vpHomogeneousMatrix &fMe) const
void get_fJw(const vpColVector &q, vpMatrix &fJw) const
Class that consider the particular case of twist transformation matrix that allows to transform a vel...
unsigned int getInverseKinematics(const vpHomogeneousMatrix &fMc, vpColVector &q, const bool &verbose=false) const
static double rad(double deg)
void get_fJe(const vpColVector &q, vpMatrix &fJe) const
vpColVector getJointMin() const
void get_cMe(vpHomogeneousMatrix &cMe) const
static double deg(double rad)
vpColVector getJointMax() const
Class that provides a data structure for the column vectors as well as a set of operations on these v...
vpHomogeneousMatrix inverse() const
Class that consider the case of the Euler angle using the x-y-z convention, where are respectively ...
unsigned int getRows() const
Return the number of rows of the matrix.
vpHomogeneousMatrix getForwardKinematics(const vpColVector &q) const
Class that consider the case of a translation vector.
static const unsigned int njoint
Number of joint.
void resize(const unsigned int i, const bool flagNullify=true)