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 #include <stdio.h>
00034 #include <stdlib.h>
00035 #include <time.h>
00036 #include <ros/ros.h>
00037 #include <pr2_arm_kinematics/pr2_arm_ik_solver.h>
00038 #include <pr2_arm_kinematics/pr2_arm_kinematics_utils.h>
00039 #include <kdl/chainfksolverpos_recursive.hpp>
00040 #include <motion_planning_msgs/ArmNavigationErrorCodes.h>
00041 
00042 #include <gtest/gtest.h>
00043 
00044 
00045 
00046 #define IK_NEAR 1e-4
00047 #define IK_NEAR_TRANSLATE 1e-5
00048 using namespace pr2_arm_kinematics;
00049 using namespace KDL;
00050 
00051 double gen_rand(double min, double max)
00052 {
00053   int rand_num = rand()%100+1;
00054   double result = min + (double)((max-min)*rand_num)/101.0;
00055   return result;
00056 }
00057 
00058 TEST(PR2ArmIK, initialize)
00059 {
00060   ros::NodeHandle nh("pr2_ik_regression_test");
00061   urdf::Model robot_model;
00062   std::string tip_name,root_name,xml_string;
00063   int free_angle;
00064   double sd;
00065   ROS_INFO("Running test");
00066   EXPECT_TRUE(loadRobotModel(nh,robot_model,root_name,tip_name,xml_string));
00067   nh.param<int>("free_angle",free_angle,2);
00068   nh.param<double>("search_discretization",sd,0.01);
00069 }
00070 
00071 bool NOT_NEAR(const double &v1, const double &v2, const double &NEAR)
00072 {
00073    if(fabs(v1-v2) > NEAR)
00074       return true;
00075    return false;
00076 }
00077 
00078 TEST(PR2ArmIK, inverseKinematics)
00079 {
00080   ros::NodeHandle nh("/pr2_ik_regression_test");
00081   urdf::Model robot_model;
00082   std::string tip_name,root_name,xml_string;
00083   int free_angle;
00084   double sd;
00085 
00086   EXPECT_TRUE(loadRobotModel(nh,robot_model,root_name,tip_name,xml_string));
00087   nh.param<int>("free_angle",free_angle,2);
00088   nh.param<double>("search_discretization",sd,0.01);
00089   pr2_arm_kinematics::PR2ArmIKSolver ik(robot_model,root_name,tip_name,sd,free_angle);
00090 
00091   KDL::Chain kdl_chain;
00092   EXPECT_TRUE(pr2_arm_kinematics::getKDLChain(xml_string,root_name,tip_name,kdl_chain));
00093 
00094   int num_tests = 10000;
00095   EXPECT_TRUE(ik.active_);
00096 
00097   KDL::ChainFkSolverPos_recursive *jnt_to_pose_solver;
00098   KDL::JntArray jnt_pos_in;
00099   KDL::JntArray jnt_pos_out;
00100   KDL::Frame p_out;
00101   KDL::Frame p_ik;
00102 
00103   srand ( time(NULL) ); 
00104 
00105   jnt_to_pose_solver = new KDL::ChainFkSolverPos_recursive(kdl_chain);
00106   jnt_pos_in.resize(7);
00107   jnt_pos_out.resize(7);
00108 
00109   kinematics_msgs::KinematicSolverInfo chain_info;
00110   ik.getSolverInfo(chain_info);
00111 
00112   int num_solutions(0);
00113 
00114   for(int kk = 0; kk < num_tests; kk++)
00115   {
00116     for(int i=0; i < 7; i++)
00117     {
00118       jnt_pos_in(i) = gen_rand(std::max(chain_info.limits[i].min_position,-M_PI),std::min(chain_info.limits[i].max_position,M_PI));
00119       EXPECT_TRUE((jnt_pos_in(i) <= chain_info.limits[i].max_position));
00120       EXPECT_TRUE((jnt_pos_in(i) >= chain_info.limits[i].min_position));
00121     }
00122 
00123     if(jnt_to_pose_solver->JntToCart(jnt_pos_in,p_out) >=0)
00124     {
00125       bool ik_valid = (ik.CartToJnt(jnt_pos_in,p_out,jnt_pos_out) >= 0);
00126       if(ik_valid)
00127       {
00128         num_solutions++;
00129         jnt_to_pose_solver->JntToCart(jnt_pos_out,p_ik);
00130         for(int j=0; j< 3; j++)
00131         {
00132           EXPECT_NEAR(p_ik.M(j,0),p_out.M(j,0),IK_NEAR);
00133           EXPECT_NEAR(p_ik.M(j,1),p_out.M(j,1),IK_NEAR); 
00134           EXPECT_NEAR(p_ik.M(j,2),p_out.M(j,2),IK_NEAR); 
00135           EXPECT_NEAR(p_ik.p(j),p_out.p(j),IK_NEAR_TRANSLATE);
00136         }
00137       }
00138     }
00139   }
00140 
00141   bool success = ((double)num_solutions)/((double) num_tests) > 0.99;
00142   ROS_INFO("Success rate is %f",((double)num_solutions)/((double) num_tests));
00143 
00144   EXPECT_TRUE(success);
00145   delete jnt_to_pose_solver;
00146 }
00147 
00148 
00149 TEST(PR2ArmIK, inverseKinematicsSearch)
00150 {
00151   ros::NodeHandle nh("/pr2_ik_regression_test");
00152   urdf::Model robot_model;
00153   std::string tip_name,root_name,xml_string;
00154   int free_angle;
00155   double sd;
00156 
00157   EXPECT_TRUE(loadRobotModel(nh,robot_model,root_name,tip_name,xml_string));
00158   nh.param<int>("free_angle",free_angle,2);
00159   nh.param<double>("search_discretization",sd,0.001);
00160   pr2_arm_kinematics::PR2ArmIKSolver ik(robot_model,root_name,tip_name,sd,free_angle);
00161 
00162   KDL::Chain kdl_chain;
00163   EXPECT_TRUE(pr2_arm_kinematics::getKDLChain(xml_string,root_name,tip_name,kdl_chain));
00164 
00165   kinematics_msgs::KinematicSolverInfo chain_info;
00166   ik.getSolverInfo(chain_info);
00167 
00168   int num_tests = 10000;
00169   KDL::ChainFkSolverPos_recursive *jnt_to_pose_solver;
00170   KDL::JntArray jnt_pos_in;
00171   KDL::JntArray jnt_pos_test;
00172   std::vector<KDL::JntArray> jnt_pos_out;
00173   KDL::Frame p_out;
00174   KDL::Frame p_ik;
00175 
00176   srand ( time(NULL) );
00177 
00178   jnt_to_pose_solver = new KDL::ChainFkSolverPos_recursive(kdl_chain);
00179   jnt_pos_in.resize(7);
00180   jnt_pos_test.resize(7);
00181 
00182   int num_solutions(0);
00183 
00184   for(int kk = 0; kk < num_tests; kk++)
00185   {
00186     ROS_INFO("Test: %d",kk);
00187     for(int i=0; i < 7; i++)
00188     {
00189       jnt_pos_in(i) = gen_rand(std::max(chain_info.limits[i].min_position,-M_PI),std::min(chain_info.limits[i].max_position,M_PI));
00190       EXPECT_TRUE((jnt_pos_in(i) <= chain_info.limits[i].max_position));
00191       EXPECT_TRUE((jnt_pos_in(i) >= chain_info.limits[i].min_position));
00192     }
00193 
00194     for(int i=0; i < 7; i++)
00195     {
00196       jnt_pos_test(i) = gen_rand(std::max(chain_info.limits[i].min_position,-M_PI),std::min(chain_info.limits[i].max_position,M_PI));
00197       EXPECT_TRUE((jnt_pos_test(i) <= chain_info.limits[i].max_position));
00198       EXPECT_TRUE((jnt_pos_test(i) >= chain_info.limits[i].min_position));
00199       }
00200 
00201     if(jnt_to_pose_solver->JntToCart(jnt_pos_in,p_out) >=0)
00202     {
00203       motion_planning_msgs::ArmNavigationErrorCodes error_code;
00204 
00205       bool ik_valid = (ik.CartToJntSearch(jnt_pos_test,p_out,jnt_pos_out,10) >= 0);
00206       if(ik_valid)
00207       {
00208         num_solutions++;
00209         for(int k=0; k < (int)jnt_pos_out.size(); k++)
00210         {
00211           jnt_to_pose_solver->JntToCart(jnt_pos_out[k],p_ik);
00212           for(int j=0; j< 3; j++)
00213           {
00214             EXPECT_NEAR(p_ik.M(j,0),p_out.M(j,0),IK_NEAR);
00215             EXPECT_NEAR(p_ik.M(j,1),p_out.M(j,1),IK_NEAR); 
00216             EXPECT_NEAR(p_ik.M(j,2),p_out.M(j,2),IK_NEAR); 
00217             EXPECT_NEAR(p_ik.p(j),p_out.p(j),IK_NEAR_TRANSLATE);
00218           }
00219 
00220 
00221         }
00222       }
00223       else
00224       {
00225         ROS_INFO("Failed solution");
00226         for(int m=0; m < 3; m++)
00227         {
00228           printf("%f %f %f %f\n",p_out.M(m,0),p_out.M(m,1),p_out.M(m,2),p_out.p(m));
00229         }
00230         printf("\n");
00231         ROS_INFO("Original joint values");
00232           for(int n = 0; n< 7; n++)
00233           {
00234             printf("%f ",jnt_pos_in(n));
00235           }
00236           printf("\n");
00237           ROS_INFO("Guess: %f",jnt_pos_test(2));
00238           
00239 
00240 
00241 
00242 
00243 
00244 
00245 
00246 
00247         ROS_INFO("\n\n\n");
00248       }
00249     }
00250   }
00251   bool success = ((double)num_solutions)/((double) num_tests) > 0.99;
00252   ROS_INFO("Success rate is %f",((double)num_solutions)/((double) num_tests));
00253 
00254   EXPECT_TRUE(success);
00255   delete jnt_to_pose_solver;
00256 }
00257 
00258 
00259 int main(int argc, char **argv){
00260   testing::InitGoogleTest(&argc, argv);
00261   ros::init (argc, argv, "pr2_ik_regression_test");
00262 
00263   return RUN_ALL_TESTS();
00264 }