int main(int argc, char** argv) { IKREAL_TYPE eerot[9],eetrans[3]; #if IK_VERSION > 54 // for IKFast 56,61 unsigned int num_of_joints = GetNumJoints(); unsigned int num_free_parameters = GetNumFreeParameters(); #else // for IKFast 54 unsigned int num_of_joints = getNumJoints(); unsigned int num_free_parameters = getNumFreeParameters(); #endif std::string cmd; if (argv[1]) cmd = argv[1]; //printf("command: %s \n\n", cmd.c_str() ); if (cmd.compare("ik") == 0) // ik mode { if( argc == 1+7+num_free_parameters+1 ) // ik, given translation vector and quaternion pose { #if IK_VERSION > 54 // for IKFast 56,61 IkSolutionList<IKREAL_TYPE> solutions; #else // for IKFast 54 std::vector<IKSolution> vsolutions; #endif std::vector<IKREAL_TYPE> vfree(num_free_parameters); eetrans[0] = atof(argv[2]); eetrans[1] = atof(argv[3]); eetrans[2] = atof(argv[4]); // Convert input effector pose, in w x y z quaternion notation, to rotation matrix. // Must use doubles, else lose precision compared to directly inputting the rotation matrix. double qw = atof(argv[5]); double qx = atof(argv[6]); double qy = atof(argv[7]); double qz = atof(argv[8]); const double n = 1.0f/sqrt(qx*qx+qy*qy+qz*qz+qw*qw); qw *= n; qx *= n; qy *= n; qz *= n; eerot[0] = 1.0f - 2.0f*qy*qy - 2.0f*qz*qz; eerot[1] = 2.0f*qx*qy - 2.0f*qz*qw; eerot[2] = 2.0f*qx*qz + 2.0f*qy*qw; eerot[3] = 2.0f*qx*qy + 2.0f*qz*qw; eerot[4] = 1.0f - 2.0f*qx*qx - 2.0f*qz*qz; eerot[5] = 2.0f*qy*qz - 2.0f*qx*qw; eerot[6] = 2.0f*qx*qz - 2.0f*qy*qw; eerot[7] = 2.0f*qy*qz + 2.0f*qx*qw; eerot[8] = 1.0f - 2.0f*qx*qx - 2.0f*qy*qy; // For debugging, output the matrix for (unsigned char i=0; i<=8; i++) { // detect -0.0 and replace with 0.0 if ( ((int&)(eerot[i]) & 0xFFFFFFFF) == 0) eerot[i] = 0.0; } printf(" Rotation %f %f %f \n", eerot[0], eerot[1], eerot[2] ); printf(" %f %f %f \n", eerot[3], eerot[4], eerot[5] ); printf(" %f %f %f \n", eerot[6], eerot[7], eerot[8] ); printf("\n"); for(std::size_t i = 0; i < vfree.size(); ++i) vfree[i] = atof(argv[13+i]); #if IK_VERSION > 54 // for IKFast 56,61 bool bSuccess = ComputeIk(eetrans, eerot, vfree.size() > 0 ? &vfree[0] : NULL, solutions); #else // for IKFast 54 bool bSuccess = ik(eetrans, eerot, vfree.size() > 0 ? &vfree[0] : NULL, vsolutions); #endif if( !bSuccess ) { fprintf(stderr,"Failed to get ik solution\n"); //return -1; } #if IK_VERSION > 54 // for IKFast 56,61 unsigned int num_of_solutions = (int)solutions.GetNumSolutions(); #else // for IKFast 54 unsigned int num_of_solutions = (int)vsolutions.size(); #endif printf("Found %d ik solutions:\n", num_of_solutions ); std::vector<IKREAL_TYPE> solvalues(num_of_joints); for(std::size_t i = 0; i < num_of_solutions; ++i) { #if IK_VERSION > 54 // for IKFast 56,61 const IkSolutionBase<IKREAL_TYPE>& sol = solutions.GetSolution(i); int this_sol_free_params = (int)sol.GetFree().size(); #else // for IKFast 54 int this_sol_free_params = (int)vsolutions[i].GetFree().size(); #endif printf("sol%d (free=%d): ", (int)i, this_sol_free_params ); std::vector<IKREAL_TYPE> vsolfree(this_sol_free_params); #if IK_VERSION > 54 // for IKFast 56,61 sol.GetSolution(&solvalues[0],vsolfree.size()>0?&vsolfree[0]:NULL); #else // for IKFast 54 vsolutions[i].GetSolution(&solvalues[0],vsolfree.size()>0?&vsolfree[0]:NULL); #endif for( std::size_t j = 0; j < solvalues.size(); ++j) printf("%.15f, ", solvalues[j]); printf("\n"); } } else if( argc == 1+12+num_free_parameters+1 ) // ik, given rotation-translation matrix { #if IK_VERSION > 54 // for IKFast 56,61 IkSolutionList<IKREAL_TYPE> solutions; #else // for IKFast 54 std::vector<IKSolution> vsolutions; #endif std::vector<IKREAL_TYPE> vfree(num_free_parameters); eerot[0] = atof(argv[2]); eerot[1] = atof(argv[3]); eerot[2] = atof(argv[4]); eetrans[0] = atof(argv[5]); eerot[3] = atof(argv[6]); eerot[4] = atof(argv[7]); eerot[5] = atof(argv[8]); eetrans[1] = atof(argv[9]); eerot[6] = atof(argv[10]); eerot[7] = atof(argv[11]); eerot[8] = atof(argv[12]); eetrans[2] = atof(argv[13]); for(std::size_t i = 0; i < vfree.size(); ++i) vfree[i] = atof(argv[14+i]); printf("translation: \n"); for (unsigned int i = 0; i < 3; i++) { printf("%lf ", eetrans[i]); } printf("\n"); printf("rotation matix: \n"); for (unsigned int i = 0; i < 9; i++) { printf("%lf%s", eerot[i], (i % 3 == 2)?"\n":" "); } printf("\n"); printf("vfree:\n"); for(std::size_t i = 0; i < vfree.size(); ++i) printf("%lf ", vfree[i]); printf("\n"); #if IK_VERSION > 54 // for IKFast 56,61 bool bSuccess = ComputeIk(eetrans, eerot, vfree.size() > 0 ? &vfree[0] : NULL, solutions); #else // for IKFast 54 bool bSuccess = ik(eetrans, eerot, vfree.size() > 0 ? &vfree[0] : NULL, vsolutions); #endif if( !bSuccess ) { fprintf(stderr,"Failed to get ik solution\n"); return -1; } #if IK_VERSION > 54 // for IKFast 56,61 unsigned int num_of_solutions = (int)solutions.GetNumSolutions(); #else // for IKFast 54 unsigned int num_of_solutions = (int)vsolutions.size(); #endif printf("Found %d ik solutions:\n", num_of_solutions ); std::vector<IKREAL_TYPE> solvalues(num_of_joints); for(std::size_t i = 0; i < num_of_solutions; ++i) { #if IK_VERSION > 54 // for IKFast 56,61 const IkSolutionBase<IKREAL_TYPE>& sol = solutions.GetSolution(i); int this_sol_free_params = (int)sol.GetFree().size(); #else // for IKFast 54 int this_sol_free_params = (int)vsolutions[i].GetFree().size(); #endif printf("sol%d (free=%d): ", (int)i, this_sol_free_params ); std::vector<IKREAL_TYPE> vsolfree(this_sol_free_params); #if IK_VERSION > 54 // for IKFast 56,61 sol.GetSolution(&solvalues[0],vsolfree.size()>0?&vsolfree[0]:NULL); #else // for IKFast 54 vsolutions[i].GetSolution(&solvalues[0],vsolfree.size()>0?&vsolfree[0]:NULL); #endif for( std::size_t j = 0; j < solvalues.size(); ++j) printf("%.15f, ", solvalues[j]); printf("\n"); } } else { printf("\n " "Usage: \n\n " " ./compute ik t0 t1 t2 qw qi qj qk free0 ...\n\n " " Returns the ik solutions given the transformation of the end effector specified by \n " " a 3x1 translation (tX), and a 1x4 quaternion (w + i + j + k). \n " " There are %d free parameters that have to be specified.\n\n", num_free_parameters ); printf(" \n " " ./compute ik r00 r01 r02 t0 r10 r11 r12 t1 r20 r21 r22 t2 free0 ...\n\n " " Returns the ik solutions given the transformation of the end effector specified by \n " " a 3x3 rotation R (rXX), and a 3x1 translation (tX). \n " " There are %d free parameters that have to be specified.\n\n", num_free_parameters ); return 1; } } // endif ik mode else if (cmd.compare("fk") == 0) // fk mode { if( argc != num_of_joints+2 ) { printf("\n " "Usage: \n\n " " ./compute fk j0 j1 ... j%d \n\n" " Returns the forward kinematic solution given the joint angles (in radians). \n\n", num_of_joints-1 ); return 1; } printf("\n\n"); // Put input joint values into array IKREAL_TYPE joints[num_of_joints]; for (unsigned int i=0; i<num_of_joints; i++) { joints[i] = atof(argv[i+2]); } #if IK_VERSION > 54 // for IKFast 56,61 ComputeFk(joints, eetrans, eerot); // void return #else // for IKFast 54 fk(joints, eetrans, eerot); // void return #endif printf("Found fk solution for end frame: \n\n"); printf(" Translation: x: %f y: %f z: %f \n", eetrans[0], eetrans[1], eetrans[2] ); printf("\n"); printf(" Rotation %f %f %f \n", eerot[0], eerot[1], eerot[2] ); printf(" Matrix: %f %f %f \n", eerot[3], eerot[4], eerot[5] ); printf(" %f %f %f \n", eerot[6], eerot[7], eerot[8] ); printf("\n"); // Display equivalent Euler angles float yaw; float pitch; float roll; if ( eerot[5] > 0.998 || eerot[5] < -0.998 ) { // singularity yaw = IKatan2( -eerot[6], eerot[0] ); pitch = 0; } else { yaw = IKatan2( eerot[2], eerot[8] ); pitch = IKatan2( eerot[3], eerot[4] ); } roll = IKasin( eerot[5] ); printf(" Euler angles: \n"); printf(" Yaw: %f ", yaw ); printf("(1st: rotation around vertical blue Z-axis in ROS Rviz) \n"); printf(" Pitch: %f \n", pitch ); printf(" Roll: %f \n", roll ); printf("\n"); // Convert rotation matrix to quaternion (Daisuke Miyazaki) float q0 = ( eerot[0] + eerot[4] + eerot[8] + 1.0f) / 4.0f; float q1 = ( eerot[0] - eerot[4] - eerot[8] + 1.0f) / 4.0f; float q2 = (-eerot[0] + eerot[4] - eerot[8] + 1.0f) / 4.0f; float q3 = (-eerot[0] - eerot[4] + eerot[8] + 1.0f) / 4.0f; if(q0 < 0.0f) q0 = 0.0f; if(q1 < 0.0f) q1 = 0.0f; if(q2 < 0.0f) q2 = 0.0f; if(q3 < 0.0f) q3 = 0.0f; q0 = sqrt(q0); q1 = sqrt(q1); q2 = sqrt(q2); q3 = sqrt(q3); if(q0 >= q1 && q0 >= q2 && q0 >= q3) { q0 *= +1.0f; q1 *= SIGN(eerot[7] - eerot[5]); q2 *= SIGN(eerot[2] - eerot[6]); q3 *= SIGN(eerot[3] - eerot[1]); } else if(q1 >= q0 && q1 >= q2 && q1 >= q3) { q0 *= SIGN(eerot[7] - eerot[5]); q1 *= +1.0f; q2 *= SIGN(eerot[3] + eerot[1]); q3 *= SIGN(eerot[2] + eerot[6]); } else if(q2 >= q0 && q2 >= q1 && q2 >= q3) { q0 *= SIGN(eerot[2] - eerot[6]); q1 *= SIGN(eerot[3] + eerot[1]); q2 *= +1.0f; q3 *= SIGN(eerot[7] + eerot[5]); } else if(q3 >= q0 && q3 >= q1 && q3 >= q2) { q0 *= SIGN(eerot[3] - eerot[1]); q1 *= SIGN(eerot[6] + eerot[2]); q2 *= SIGN(eerot[7] + eerot[5]); q3 *= +1.0f; } else { printf("Error while converting to quaternion! \n"); } float r = NORM(q0, q1, q2, q3); q0 /= r; q1 /= r; q2 /= r; q3 /= r; printf(" Quaternion: %f %f %f %f \n", q0, q1, q2, q3 ); printf(" "); // print quaternion with convention and +/- signs such that it can be copy-pasted into WolframAlpha.com printf("%f ", q0); if (q1 > 0) printf("+ %fi ", q1); else if (q1 < 0) printf("- %fi ", -q1); else printf("+ 0.00000i "); if (q2 > 0) printf("+ %fj ", q2); else if (q2 < 0) printf("- %fj ", -q2); else printf("+ 0.00000j "); if (q3 > 0) printf("+ %fk ", q3); else if (q3 < 0) printf("- %fk ", -q3); else printf("+ 0.00000k "); printf(" (alternate convention) \n"); printf("\n\n"); } else if (cmd.compare("iktiming") == 0) // generate random ik and check time performance { if( argc != 2 ) { printf("\n " "Usage: \n\n " " ./compute iktiming \n\n" " For fixed number of iterations, generates random joint angles, then \n" " calculates fk, calculates ik, measures average time taken. \n\n", num_of_joints-1 ); return 1; } printf("\n\n"); #if IK_VERSION > 54 // for IKFast 56,61 IkSolutionList<IKREAL_TYPE> solutions; #else // for IKFast 54 std::vector<IKSolution> vsolutions; #endif std::vector<IKREAL_TYPE> vfree(num_free_parameters); //for(std::size_t i = 0; i < vfree.size(); ++i) // vfree[i] = atof(argv[13+i]); srand( (unsigned)time(0) ); // seed random number generator float min = -3.14; float max = 3.14; float rnd; IKREAL_TYPE joints[num_of_joints]; timespec start_time, end_time; unsigned int elapsed_time = 0; unsigned int sum_time = 0; unsigned int fail_count = 0; #if IK_VERSION > 54 // for IKFast 56,61 unsigned int num_of_tests = 10; #else // for IKFast 54 unsigned int num_of_tests = 100000; #endif for (unsigned int i=0; i < num_of_tests; i++) { // Measure avg time for whole process //clock_gettime(CLOCK_REALTIME, &start_time); // Put random joint values into array for (unsigned int i=0; i<num_of_joints; i++) { float rnd = (float)rand() / (float)RAND_MAX; joints[i] = min + rnd * (max - min); } /* printf("Joint angles: "); for (unsigned int i=0; i<num_of_joints; i++) { printf("%f ", joints[i] ); } printf("\n"); */ #if IK_VERSION > 54 // for IKFast 56,61 ComputeFk(joints, eetrans, eerot); // void return #else // for IKFast 54 fk(joints, eetrans, eerot); // void return #endif // Measure avg time for IK clock_gettime(CLOCK_REALTIME, &start_time); #if IK_VERSION > 54 // for IKFast 56,61 vfree[0] = 5; if (!ComputeIk(eetrans, eerot, vfree.size() > 0 ? &vfree[0] : NULL, solutions)) { fail_count++; } else { printf("joint angles: \n"); for (unsigned int i=0; i<num_of_joints; i++) { printf("%lf ", joints[i]); } printf("\n"); printf("translation: \n"); for (unsigned int i = 0; i < 3; i++) { printf("%lf ", eetrans[i]); } printf("\n"); printf("rotation matix: \n"); for (unsigned int i = 0; i < 9; i++) { printf("%lf%s", eerot[i], (i % 3 == 2)?"\n":" "); } printf("\n"); /*unsigned int num_of_solutions = (int)solutions.GetNumSolutions(); printf("Found %d ik solutions:\n", num_of_solutions ); std::vector<IKREAL_TYPE> solvalues(num_of_joints); for(std::size_t i = 0; i < num_of_solutions; ++i) { const IkSolutionBase<IKREAL_TYPE>& sol = solutions.GetSolution(i); int this_sol_free_params = (int)sol.GetFree().size(); printf("sol%d (free=%d): ", (int)i, this_sol_free_params ); std::vector<IKREAL_TYPE> vsolfree(this_sol_free_params); sol.GetSolution(&solvalues[0],vsolfree.size()>0?&vsolfree[0]:NULL); for( std::size_t j = 0; j < solvalues.size(); ++j) printf("%.15f, ", solvalues[j]); printf("\n"); }*/ } #else // for IKFast 54 ik(eetrans, eerot, vfree.size() > 0 ? &vfree[0] : NULL, vsolutions); #endif /* #if IK_VERSION > 54 // for IKFast 56,61 unsigned int num_of_solutions = (int)solutions.GetNumSolutions(); #else // for IKFast 54 unsigned int num_of_solutions = (int)vsolutions.size(); #endif printf("Found %d ik solutions:\n", num_of_solutions ); */ clock_gettime(CLOCK_REALTIME, &end_time); elapsed_time = (unsigned int)(end_time.tv_nsec - start_time.tv_nsec); sum_time += elapsed_time; } // endfor unsigned int avg_time = (unsigned int)sum_time / (unsigned int)num_of_tests; printf("avg time: %f ms over %d tests \n", (float)avg_time/1000.0, num_of_tests ); printf("Failed of %d tests\n", fail_count); return 1; } else if (cmd.compare("iktiming2") == 0) // for fixed joint values, check time performance of ik { if( argc != 2 ) { printf("\n " "Usage: \n\n " " ./compute iktiming2 \n\n" " For fixed number of iterations, with one set of joint variables, this \n" " finds the ik solutions and measures the average time taken. \n\n", num_of_joints-1 ); return 1; } printf("\n\n"); #if IK_VERSION > 54 // for IKFast 56,61 IkSolutionList<IKREAL_TYPE> solutions; #else // for IKFast 54 std::vector<IKSolution> vsolutions; #endif std::vector<IKREAL_TYPE> vfree(num_free_parameters); //for(std::size_t i = 0; i < vfree.size(); ++i) // vfree[i] = atof(argv[13+i]); IKREAL_TYPE joints[num_of_joints]; timespec start_time, end_time; unsigned int elapsed_time = 0; unsigned int sum_time = 0; #if IK_VERSION > 54 // for IKFast 56,61 unsigned int num_of_tests = 1000000; #else // for IKFast 54 unsigned int num_of_tests = 100000; #endif // fixed rotation-translation matrix corresponding to an unusual robot pose eerot[0] = 0.002569; eerot[1] = -0.658044; eerot[2] = -0.752975; eetrans[0] = 0.121937; eerot[3] = 0.001347; eerot[4] = -0.752975; eerot[5] = 0.658048; eetrans[1] = -0.276022; eerot[6] = -0.999996; eerot[7] = -0.002705; eerot[8] = -0.001047; eetrans[2] = 0.005685; for (unsigned int i=0; i < num_of_tests; i++) { clock_gettime(CLOCK_REALTIME, &start_time); #if IK_VERSION > 54 // for IKFast 56,61 ComputeIk(eetrans, eerot, vfree.size() > 0 ? &vfree[0] : NULL, solutions); #else // for IKFast 54 ik(eetrans, eerot, vfree.size() > 0 ? &vfree[0] : NULL, vsolutions); #endif /* #if IK_VERSION > 54 // for IKFast 56,61 unsigned int num_of_solutions = (int)solutions.GetNumSolutions(); #else // for IKFast 54 unsigned int num_of_solutions = (int)vsolutions.size(); #endif printf("Found %d ik solutions:\n", num_of_solutions ); */ clock_gettime(CLOCK_REALTIME, &end_time); elapsed_time = (unsigned int)(end_time.tv_nsec - start_time.tv_nsec); sum_time += elapsed_time; } // endfor unsigned int avg_time = (unsigned int)sum_time / (unsigned int)num_of_tests; printf("avg time: %f ms over %d tests \n", (float)avg_time/1000.0, num_of_tests ); return 1; } else { printf("\n" "Usage: \n\n"); printf(" ./compute fk j0 j1 ... j%d \n\n" " Returns the forward kinematic solution given the joint angles (in radians). \n\n", num_of_joints-1 ); printf("\n" " ./compute ik t0 t1 t2 qw qi qj qk free0 ... \n\n" " Returns the ik solutions given the transformation of the end effector specified by \n" " a 3x1 translation (tX), and a 1x4 quaternion (w + i + j + k). \n" " There are %d free parameters that have to be specified. \n\n", num_free_parameters ); printf(" \n" " ./compute ik r00 r01 r02 t0 r10 r11 r12 t1 r20 r21 r22 t2 free0 ...\n\n" " Returns the ik solutions given the transformation of the end effector specified by \n" " a 3x3 rotation R (rXX), and a 3x1 translation (tX). \n" " There are %d free parameters that have to be specified. \n\n", num_free_parameters ); printf("\n" " ./compute iktiming \n\n" " For fixed number of iterations, generates random joint angles, then \n" " calculates fk, calculates ik, measures average time taken. \n\n", num_of_joints-1 ); printf("\n" " ./compute iktiming2 \n\n" " For fixed number of iterations, with one set of joint variables, this \n" " finds the ik solutions and measures the average time taken. \n\n", num_of_joints-1 ); return 1; } return 0; }
int main(int argc, char *argv[]) { if (argc < 2){ std::cerr << "Usage:" << argv[0] << "[-checkLimits]" << std::endl; } const char *url="file:///home/kanehiro/src/HRP2/model/HRP2main.wrl"; int arm = 0; bool checkLimits=false; bool display=true; for (int i=1; i<argc; i++){ if(strcmp(argv[i], "-checkLimits")==0){ checkLimits = true; }else if(strcmp(argv[i], "-nodisplay")==0){ display = false; } } std::cout << "arm=" << arm << std::endl; std::cout << "checkLimits=" << checkLimits << std::endl; HumanoidBodyPtr body = HumanoidBodyPtr(new HumanoidBody()); if (!loadHumanoidBodyFromModelLoader(body, url, argc, argv)){ std::cerr << "failed to load model[" << url << "]" << std::endl; return 1; } OpenHRP::OnlineViewer_var olv; if (display){ olv = hrp::getOnlineViewer(argc, argv); olv->load(body->name().c_str(), url); olv->clearLog(); } OpenHRP::WorldState wstate; wstate.time = 0.0; wstate.characterPositions.length(1); setupCharacterPosition(wstate.characterPositions[0], body); wstate.collisions.length(1); hrp::JointPathPtr jp; if (arm == 0){ jp = body->getJointPath(body->link("CHEST_JOINT1"), body->link("RARM_JOINT5")); }else{ jp = body->getJointPath(body->link("CHEST_JOINT1"), body->link("LARM_JOINT5")); } hrp::Vector3 p; hrp::Matrix33 R = hrp::rotFromRpy(0, -M_PI/2, 0); double startx=-0.3, starty=-1.0, startz=1.0; double endx=0.7, endy=0.5, endz=2.0; if (arm != 0){ double tmp = starty; starty = -endy; endy = -tmp; } wstate.collisions[0].points.length(12); updateLineSegment(wstate.collisions[0].points[0], hrp::Vector3(startx, starty, startz), hrp::Vector3(endx, starty, startz)); updateLineSegment(wstate.collisions[0].points[1], hrp::Vector3(startx, starty, startz), hrp::Vector3(startx, endy, startz)); updateLineSegment(wstate.collisions[0].points[2], hrp::Vector3(startx, starty, startz), hrp::Vector3(startx, starty, endz)); updateLineSegment(wstate.collisions[0].points[3], hrp::Vector3(endx, endy, startz), hrp::Vector3(startx, endy, startz)); updateLineSegment(wstate.collisions[0].points[4], hrp::Vector3(endx, endy, startz), hrp::Vector3(endx, starty, startz)); updateLineSegment(wstate.collisions[0].points[5], hrp::Vector3(endx, endy, startz), hrp::Vector3(endx, endy, endz)); updateLineSegment(wstate.collisions[0].points[6], hrp::Vector3(endx, starty, endz), hrp::Vector3(endx, starty, startz)); updateLineSegment(wstate.collisions[0].points[7], hrp::Vector3(endx, starty, endz), hrp::Vector3(startx, starty, endz)); updateLineSegment(wstate.collisions[0].points[8], hrp::Vector3(endx, starty, endz), hrp::Vector3(endx, endy, endz)); updateLineSegment(wstate.collisions[0].points[9], hrp::Vector3(startx, endy, endz), hrp::Vector3(endx, endy, endz)); updateLineSegment(wstate.collisions[0].points[10], hrp::Vector3(startx, endy, endz), hrp::Vector3(startx, endy, startz)); updateLineSegment(wstate.collisions[0].points[11], hrp::Vector3(startx, endy, endz), hrp::Vector3(startx, starty, endz)); double step=0.05; int total=0, success=0; IkSolutionList<IkReal> solutions; IkReal eerot[9],eetrans[3]; std::vector<IkReal> solvalues(GetNumJoints()); double linErr=0, angErr=0; struct timeval begin, end; gettimeofday(&begin, NULL); for (double x=startx; x<endx; x+=step){ for (double y=starty; y<endy; y+=step){ for (double z=startz; z<endz; z+=step){ total++; p << x,y,z; if (display) std::cout << "testing " << p.transpose() << " - "; #if 0 bool ret = jp->calcInverseKinematics(p, R); if (ret && checkLimits){ for (int i=0; i<jp->numJoints(); i++){ hrp::Link *j = jp->joint(i); if (j->q > j->ulimit || j->q < j->llimit){ std::cout << "fail\r" << std::flush; ret = false; break; } } } #else hrp::Vector3 relP; hrp::Matrix33 relR; relR = jp->baseLink()->R.transpose() * R; relP = jp->baseLink()->R.transpose() * (p - jp->baseLink()->p); for (int i=0; i<3; i++){ eetrans[i] = relP[i]; for (int j=0; j<3; j++){ eerot[i*3+j] = relR(i,j); } } bool ret = ComputeIk(eetrans, eerot, NULL, solutions); if (ret) { ret = false; for (int j=0; j<solutions.GetNumSolutions(); j++){ const IkSolutionBase<IkReal>& sol = solutions.GetSolution(j); sol.GetSolution(&solvalues[0],NULL); bool found=true; for (int i=0; i<jp->numJoints(); i++){ hrp::Link *l = jp->joint(i); if (solvalues[i] > l->ulimit || solvalues[i] < l->llimit) { found = false; break; }else{ l->q = solvalues[i]; } } if (found) { ret = true; jp->calcForwardKinematics(); double perr = (jp->endLink()->p - p).norm(); if (perr > linErr) linErr = perr; double ang = hrp::omegaFromRot(jp->endLink()->R.transpose()*R).norm(); if (ang > angErr) angErr = ang; break; } } } if (!ret && display){ std::cout << "fail\r" << std::flush; } #endif if (ret) success++; if (display){ if (ret){ std::cout << "success\r" << std::flush; unsigned int len = wstate.collisions[0].points.length(); wstate.collisions[0].points.length(len+1); updateLineSegment(wstate.collisions[0].points[len], p, R*hrp::Vector3(0,0,-0.01)+p); updateView(olv, wstate, body); }else{ std::cout << "fail\r" << std::flush; } } } } } gettimeofday(&end, NULL); std::cout << std::endl; std::cout << "result:" << success << "/" << total << "(" << ((double)success)/total*100 << "%)" << std::endl; std::cout << "computation time:" << (end.tv_sec - begin.tv_sec)*1e3 + (end.tv_usec - begin.tv_usec)*1e-3 << "[ms]" << std::endl; std::cout << "maximum err:" << linErr << "[m], " << angErr << "[rad]" << std::endl; return 0; }