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>
81 c56 = -341.33 / 9102.22;
151 vpViper::convertJointPositionInLimits(
unsigned int joint,
const double &q,
double &q_mod,
const bool &verbose)
170 std::cout <<
"Joint " << joint <<
" not in limits: "
171 << this->
joint_min[joint] <<
" < " << q <<
" < " << this->
joint_max[joint] << std::endl;
235 for (
unsigned int i=0; i<8; i++)
238 double c1[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
239 double s1[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
240 double c3[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
241 double s3[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
242 double c23[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
243 double s23[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
244 double c4[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
245 double s4[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
246 double c5[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
247 double s5[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
248 double c6[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
249 double s6[8]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
256 for (
unsigned int i=0; i< 8; i++)
259 double px = fMw[0][3];
260 double py = fMw[1][3];
261 double pz = fMw[2][3];
264 double a_2 = px*px+py*py;
266 if (std::fabs(a_2) <= std::numeric_limits<double>::epsilon()) {
269 c1[4] = cos(q[0]+M_PI);
270 s1[4] = sin(q[0]+M_PI);
273 double a = sqrt(a_2);
281 for(
unsigned int i=0;i<8;i+=4) {
282 q_sol[i][0] = atan2(s1[i],c1[i]);
283 if (convertJointPositionInLimits(0, q_sol[i][0], q1_mod, verbose) ==
true) {
284 q_sol[i][0] = q1_mod;
285 for(
unsigned int j=1;j<4;j++) {
288 q_sol[i+j][0] = q_sol[i][0];
292 for(
unsigned int j=1;j<4;j++)
299 for(
unsigned int i=0; i<8; i+=4) {
302 - 2*(
a1*c1[i]*px +
a1*s1[i]*py +
d1*pz)) / (2*
a2);
305 q_sol[i][2] = atan2(
a3,
d4) + atan2(K, sqrt(d4_a3_K));
306 q_sol[i+2][2] = atan2(
a3,
d4) + atan2(K, -sqrt(d4_a3_K));
308 for (
unsigned int j=0; j<4; j+=2) {
310 for(
unsigned int k=0; k<2; k++)
314 if (convertJointPositionInLimits(2, q_sol[i+j][2], q3_mod, verbose) ==
true) {
315 for(
unsigned int k=0; k<2; k++) {
316 q_sol[i+j+k][2] = q3_mod;
317 c3[i+j+k] = cos(q3_mod);
318 s3[i+j+k] = sin(q3_mod);
322 for(
unsigned int k=0; k<2; k++)
335 double q23[8], q2_mod;
336 for (
unsigned int i=0; i<8; i+=2) {
339 c23[i] = (-(
a3-
a2*c3[i])*(c1[i]*px+s1[i]*py-
a1)-(
d1-pz)*(
d4+
a2*s3[i]))
340 / ( (c1[i]*px+s1[i]*py-
a1)*(c1[i]*px+s1[i]*py-
a1) +(
d1-pz)*(
d1-pz) );
341 s23[i] = ((
d4+
a2*s3[i])*(c1[i]*px+s1[i]*py-
a1)-(
d1-pz)*(
a3-
a2*c3[i]))
342 / ( (c1[i]*px+s1[i]*py-
a1)*(c1[i]*px+s1[i]*py-
a1) +(
d1-pz)*(
d1-pz) );
343 q23[i] = atan2(s23[i],c23[i]);
346 q_sol[i][1] = q23[i] - q_sol[i][2];
348 if (convertJointPositionInLimits(1, q_sol[i][1], q2_mod, verbose) ==
true) {
349 for(
unsigned int j=0; j<2; j++) {
350 q_sol[i+j][1] = q2_mod;
356 for(
unsigned int j=0; j<2; j++)
367 double r13 = fMw[0][2];
368 double r23 = fMw[1][2];
369 double r33 = fMw[2][2];
370 double s4s5, c4s5, q4_mod, q5_mod;
371 for (
unsigned int i=0; i<8; i+=2) {
373 s4s5 = -s1[i]*r13+c1[i]*r23;
374 c4s5 = c1[i]*c23[i]*r13+s1[i]*c23[i]*r23-s23[i]*r33;
377 c5[i] = c1[i]*s23[i]*r13+s1[i]*s23[i]*r23+c23[i]*r33;
384 if (convertJointPositionInLimits(4, q_sol[i][4], q5_mod, verbose) ==
true) {
385 for(
unsigned int j=0; j<2; j++) {
386 q_sol[i+j][3] = q[3];
387 q_sol[i+j][4] = q5_mod;
388 c4[i] = cos(q_sol[i+j][3]);
389 s4[i] = sin(q_sol[i+j][3]);
393 for(
unsigned int j=0; j<2; j++)
400 if (std::fabs(c4s5) <= std::numeric_limits<double>::epsilon()) {
404 q_sol[i][3] = atan2(s4s5, c4s5);
407 q_sol[i][3] = atan2(s4s5, c4s5);
409 if (convertJointPositionInLimits(3, q_sol[i][3], q4_mod, verbose) ==
true) {
410 q_sol[i][3] = q4_mod;
417 if (q_sol[i][3] > 0.)
418 q_sol[i+1][3] = q_sol[i][3] + M_PI;
420 q_sol[i+1][3] = q_sol[i][3] - M_PI;
421 if (convertJointPositionInLimits(3, q_sol[i+1][3], q4_mod, verbose) ==
true) {
422 q_sol[i+1][3] = q4_mod;
423 c4[i+1] = cos(q4_mod);
424 s4[i+1] = sin(q4_mod);
431 for (
unsigned int j=0; j<2; j++) {
432 if (ok[i+j] ==
true) {
433 c5[i+j] = c1[i+j]*s23[i+j]*r13+s1[i+j]*s23[i+j]*r23+c23[i+j]*r33;
434 s5[i+j] = (c1[i+j]*c23[i+j]*c4[i+j]-s1[i+j]*s4[i+j])*r13
435 +(s1[i+j]*c23[i+j]*c4[i+j]+c1[i+j]*s4[i+j])*r23-s23[i+j]*c4[i+j]*r33;
437 q_sol[i+j][4] = atan2(s5[i+j], c5[i+j]);
438 if (convertJointPositionInLimits(4, q_sol[i+j][4], q5_mod, verbose) ==
true) {
439 q_sol[i+j][4] = q5_mod;
453 double r12 = fMw[0][1];
454 double r22 = fMw[1][1];
455 double r32 = fMw[2][1];
457 for (
unsigned int i=0; i<8; i++) {
458 c6[i] = -(c1[i]*c23[i]*s4[i]+s1[i]*c4[i])*r12
459 +(c1[i]*c4[i]-s1[i]*c23[i]*s4[i])*r22+s23[i]*s4[i]*r32;
460 s6[i] = -(c1[i]*c23[i]*c4[i]*c5[i]-c1[i]*s23[i]*s5[i]
461 -s1[i]*s4[i]*c5[i])*r12
462 -(s1[i]*c23[i]*c4[i]*c5[i]-s1[i]*s23[i]*s5[i]+c1[i]*s4[i]*c5[i])*r22
463 +(c23[i]*s5[i]+s23[i]*c4[i]*c5[i])*r32;
465 q_sol[i][5] = atan2(s6[i], c6[i]);
466 if (convertJointPositionInLimits(5, q_sol[i][5], q6_mod, verbose) ==
true) {
467 q_sol[i][5] = q6_mod;
475 unsigned int nbsol = 0;
476 unsigned int sol = 0;
478 for (
unsigned int i=0; i<8; i++) {
486 weight[1] = weight[2] = 4;
488 for (
unsigned int j=0; j< 6; j++) {
489 double rought_dist = q[j]- q_sol[i][j];
490 double modulo_dist = rought_dist;
491 if (rought_dist > 0) {
492 if (fabs(rought_dist - 2*M_PI) < fabs(rought_dist))
493 modulo_dist = rought_dist - 2*M_PI;
496 if (fabs(rought_dist + 2*M_PI) < fabs(rought_dist))
497 modulo_dist = rought_dist + 2*M_PI;
507 for (
unsigned int i=0; i<8; i++) {
509 if (dist[i] < dist[sol]) sol = i;
653 fMc = fMe * this->
eMc;
761 double c23 = cos(q2+q3);
762 double s23 = sin(q2+q3);
764 fMe[0][0] = c1*(c23*(c4*c5*c6-s4*s6)-s23*s5*c6)-s1*(s4*c5*c6+c4*s6);
765 fMe[1][0] = -s1*(c23*(-c4*c5*c6+s4*s6)+s23*s5*c6)+c1*(s4*c5*c6+c4*s6);
766 fMe[2][0] = s23*(s4*s6-c4*c5*c6)-c23*s5*c6;
768 fMe[0][1] = -c1*(c23*(c4*c5*s6+s4*c6)-s23*s5*s6)+s1*(s4*c5*s6-c4*c6);
769 fMe[1][1] = -s1*(c23*(c4*c5*s6+s4*c6)-s23*s5*s6)-c1*(s4*c5*s6-c4*c6);
770 fMe[2][1] = s23*(c4*c5*s6+s4*c6)+c23*s5*s6;
772 fMe[0][2] = c1*(c23*c4*s5+s23*c5)-s1*s4*s5;
773 fMe[1][2] = s1*(c23*c4*s5+s23*c5)+c1*s4*s5;
774 fMe[2][2] = -s23*c4*s5+c23*c5;
776 fMe[0][3] = c1*(c23*(c4*s5*
d6-
a3)+s23*(c5*
d6+
d4)+
a1+
a2*c2)-s1*s4*s5*
d6;
777 fMe[1][3] = s1*(c23*(c4*s5*
d6-
a3)+s23*(c5*
d6+
d4)+
a1+
a2*c2)+c1*s4*s5*
d6;
857 double c23 = cos(q2+q3);
858 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];
1277 <<
"Joint Max (deg):" << std::endl
1278 <<
"\t" << jmax.
t() << std::endl
1280 <<
"Joint Min (deg): " << std::endl
1281 <<
"\t" << jmin.
t() << std::endl
1283 <<
"Coupling 5-6:" << std::endl
1284 <<
"\t" << viper.
c56 << std::endl
1286 <<
"eMc: "<< std::endl
1287 <<
"\tTranslation (m): "
1288 << viper.
eMc[0][3] <<
" "
1289 << viper.
eMc[1][3] <<
" "
1291 <<
"\t" << std::endl
1292 <<
"\tRotation Rxyz (rad) : "
1296 <<
"\t" << std::endl
1297 <<
"\tRotation Rxyz (deg) : "
1301 <<
"\t" << std::endl;
Definition of the vpMatrix class.
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.
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
void get_eJe(const vpColVector &q, vpMatrix &eJe)
void setIdentity()
Basic initialisation (identity)
vpColVector getJointMin()
The vpRotationMatrix considers the particular case of a rotation matrix.
double c56
Mechanical coupling between joint 5 and joint 6.
void get_eMc(vpHomogeneousMatrix &eMc)
vpVelocityTwistMatrix buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
static double sqr(double x)
vpRowVector t() const
transpose of Vector
void get_fMe(const vpColVector &q, vpHomogeneousMatrix &fMe)
void extract(vpRotationMatrix &R) const
Class that consider the particular case of twist transformation matrix that allows to transform a vel...
VISP_EXPORT std::ostream & operator<<(std::ostream &os, const vpImagePoint &ip)
static double rad(double deg)
void get_fJe(const vpColVector &q, vpMatrix &fJe)
vpColVector getJointMax()
static double deg(double rad)
void get_wMe(vpHomogeneousMatrix &wMe)
Class that provides a data structure for the column vectors as well as a set of operations on these v...
vpHomogeneousMatrix inverse() const
unsigned int getInverseKinematicsWrist(const vpHomogeneousMatrix &fMw, vpColVector &q, const bool &verbose=false)
void get_fJw(const vpColVector &q, vpMatrix &fJw)
void get_cMe(vpHomogeneousMatrix &cMe)
Class that consider the case of the Euler angle using the x-y-z convention, where are respectively ...
void get_cVe(vpVelocityTwistMatrix &cVe)
unsigned int getRows() const
Return the number of rows of the matrix.
Class that consider the case of a translation vector.
unsigned int getInverseKinematics(const vpHomogeneousMatrix &fMc, vpColVector &q, const bool &verbose=false)
static const unsigned int njoint
Number of joint.
vpHomogeneousMatrix get_fMc(const vpColVector &q)
vpHomogeneousMatrix getForwardKinematics(const vpColVector &q)
void resize(const unsigned int i, const bool flagNullify=true)
void get_fMw(const vpColVector &q, vpHomogeneousMatrix &fMw)