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
00034
00035
00036
00037
00038 #include <ros/ros.h>
00039 #include <gtest/gtest.h>
00040 #include <pluginlib/class_loader.h>
00041
00042 #include <kinematics_base/kinematics_base.h>
00043
00044
00045 #include <robot_model/robot_model.h>
00046 #include <robot_state/robot_state.h>
00047 #include <rdf_loader/rdf_loader.h>
00048 #include <urdf_interface/model.h>
00049 #include <urdf/model.h>
00050 #include <srdf/model.h>
00051
00052 #define IK_NEAR 1e-4
00053 #define IK_NEAR_TRANSLATE 1e-5
00054
00055 class MyTest
00056 {
00057 public:
00058 bool initialize()
00059 {
00060 double search_discretization;
00061 ros::NodeHandle nh("~");
00062 kinematics_solver = NULL;
00063 kinematics_loader.reset(new pluginlib::ClassLoader<kinematics::KinematicsBase>("kinematics_base", "kinematics::KinematicsBase"));
00064 std::string plugin_name;
00065 if (!nh.getParam("plugin_name", plugin_name))
00066 {
00067 ROS_ERROR("No plugin name found on parameter server");
00068 EXPECT_TRUE(0);
00069 return false;
00070 }
00071 ROS_INFO("Plugin name: %s",plugin_name.c_str());
00072 try
00073 {
00074 kinematics_solver = kinematics_loader->createClassInstance(plugin_name);
00075 }
00076 catch(pluginlib::PluginlibException& ex)
00077 {
00078 ROS_ERROR("The plugin failed to load. Error: %s", ex.what());
00079 EXPECT_TRUE(0);
00080 return false;
00081 }
00082 std::string root_name, tip_name;
00083 ros::WallTime start_time = ros::WallTime::now();
00084 bool done = true;
00085 while((ros::WallTime::now()-start_time).toSec() <= 5.0)
00086 {
00087 if (!nh.getParam("root_name", root_name))
00088 {
00089 ROS_ERROR("No root name found on parameter server");
00090 done = false;
00091 EXPECT_TRUE(0);
00092 continue;
00093 }
00094 if (!nh.getParam("tip_name", tip_name))
00095 {
00096 ROS_ERROR("No tip name found on parameter server");
00097 done = false;
00098 EXPECT_TRUE(0);
00099 continue;
00100 }
00101 if (!nh.getParam("search_discretization", search_discretization))
00102 {
00103 ROS_ERROR("No search discretization found on parameter server");
00104 done = false;
00105 EXPECT_TRUE(0);
00106 continue;
00107 }
00108 done = true;
00109 }
00110
00111 if(!done)
00112 return false;
00113
00114 if(kinematics_solver->initialize("right_arm",root_name,tip_name,search_discretization))
00115 return true;
00116 else
00117 {
00118 EXPECT_TRUE(0);
00119 return false;
00120 }
00121
00122 };
00123
00124 void pose_callback(const geometry_msgs::Pose &ik_pose,
00125 const std::vector<double> &joint_state,
00126 moveit_msgs::MoveItErrorCodes &error_code)
00127 {
00128 error_code.val = error_code.SUCCESS;
00129 };
00130
00131 void joint_state_callback(const geometry_msgs::Pose &ik_pose,
00132 const std::vector<double> &joint_state,
00133 moveit_msgs::MoveItErrorCodes &error_code)
00134 {
00135 std::vector<std::string> link_names;
00136 link_names.push_back("r_elbow_flex_link");
00137 std::vector<geometry_msgs::Pose> solutions;
00138 solutions.resize(1);
00139 if(!kinematics_solver->getPositionFK(link_names,joint_state,solutions))
00140 error_code.val = error_code.PLANNING_FAILED;
00141 if(solutions[0].position.z > 0.0)
00142 error_code.val = error_code.SUCCESS;
00143 else
00144 error_code.val = error_code.PLANNING_FAILED;
00145 };
00146 kinematics::KinematicsBase* kinematics_solver;
00147 boost::shared_ptr<pluginlib::ClassLoader<kinematics::KinematicsBase> > kinematics_loader;
00148 };
00149
00150 MyTest my_test;
00151
00152 TEST(ArmIKPlugin, initialize)
00153 {
00154 ASSERT_TRUE(my_test.initialize());
00155
00156 std::string root_name = my_test.kinematics_solver->getBaseFrame();
00157 EXPECT_TRUE(root_name == std::string("torso_lift_link"));
00158 std::string tool_name = my_test.kinematics_solver->getTipFrame();
00159 EXPECT_TRUE(tool_name == std::string("r_wrist_roll_link"));
00160 std::vector<std::string> joint_names = my_test.kinematics_solver->getJointNames();
00161 EXPECT_EQ((int)joint_names.size(), 7);
00162
00163 EXPECT_EQ(joint_names[0], "r_shoulder_pan_joint");
00164 EXPECT_EQ(joint_names[1], "r_shoulder_lift_joint");
00165 EXPECT_EQ(joint_names[2], "r_upper_arm_roll_joint");
00166 EXPECT_EQ(joint_names[3], "r_elbow_flex_joint");
00167 EXPECT_EQ(joint_names[4], "r_forearm_roll_joint");
00168 EXPECT_EQ(joint_names[5], "r_wrist_flex_joint");
00169 EXPECT_EQ(joint_names[6], "r_wrist_roll_joint");
00170 }
00171
00172 TEST(ArmIKPlugin, getFK)
00173 {
00174 rdf_loader::RDFLoader rdf_loader_;
00175 robot_model::RobotModelPtr kinematic_model;
00176 const boost::shared_ptr<srdf::Model> &srdf = rdf_loader_.getSRDF();
00177 const boost::shared_ptr<urdf::ModelInterface>& urdf_model = rdf_loader_.getURDF();
00178 robot_model.reset(new robot_model::RobotModel(urdf_model, srdf));
00179 robot_model::RobotModel::JointModelGroup* joint_model_group = kinematic_model->getJointModelGroup(my_test.kinematics_solver->getGroupName());
00180
00181 std::vector<double> seed, fk_values, solution;
00182 moveit_msgs::MoveItErrorCodes error_code;
00183 solution.resize(my_test.kinematics_solver->getJointNames().size(), 0.0);
00184
00185 std::vector<std::string> fk_names;
00186 fk_names.push_back(my_test.kinematics_solver->getTipFrame());
00187
00188 robot_model::RobotState *kinematic_state(kinematic_model);
00189 robot_state::RobotState::JointStateGroup joint_state_group(&kinematic_state,
00190 (const planning_models::RobotModel::JointModelGroup*) joint_model_group);
00191
00192 ros::NodeHandle nh("~");
00193 unsigned int number_fk_tests;
00194 nh.param("number_fk_tests", number_fk_tests, 100);
00195
00196 for(unsigned int i=0; i < number_fk_tests; ++i)
00197 {
00198 seed.resize(my_test.kinematics_solver->getJointNames().size(), 0.0);
00199 fk_values.resize(my_test.kinematics_solver->getJointNames().size(), 0.0);
00200
00201 joint_state_group.setToRandomValues();
00202 joint_state_group.getGroupStateValues(fk_values);
00203
00204 std::vector<geometry_msgs::Pose> poses;
00205 poses.resize(1);
00206 bool result_fk = my_test.kinematics_solver->getPositionFK(fk_names, fk_values, poses);
00207 ASSERT_TRUE(result_fk);
00208 }
00209 }
00210
00211 TEST(ArmIKPlugin, searchIK)
00212 {
00213 rdf_loader::RDFLoader rdf_loader_;
00214 robot_model::RobotModelPtr kinematic_model;
00215 const boost::shared_ptr<srdf::Model> &srdf_model = rdf_loader_.getSRDF();
00216 const boost::shared_ptr<urdf::ModelInterface>& urdf_model = rdf_loader_.getURDF();
00217 robot_model.reset(new planning_models::RobotModel(urdf_model, srdf));
00218 planning_models::RobotModel::JointModelGroup* joint_model_group = kinematic_model->getJointModelGroup(my_test.kinematics_solver->getGroupName());
00219
00220
00221 std::vector<double> seed, fk_values, solution;
00222 double timeout = 5.0;
00223 moveit_msgs::MoveItErrorCodes error_code;
00224 solution.resize(my_test.kinematics_solver->getJointNames().size(), 0.0);
00225
00226 std::vector<std::string> fk_names;
00227 fk_names.push_back(my_test.kinematics_solver->getTipFrame());
00228
00229 planning_models::RobotState *kinematic_state(kinematic_model);
00230 planning_models::RobotState *::JointStateGroup joint_state_group(&kinematic_state, (const planning_models::RobotModel::JointModelGroup*) joint_model_group);
00231
00232 ros::NodeHandle nh("~");
00233 unsigned int number_ik_tests;
00234 nh.param("number_ik_tests", number_ik_tests, 10);
00235 unsigned int success = 0;
00236
00237 ros::WallTime start_time = ros::WallTime::now();
00238 for(unsigned int i=0; i < number_ik_tests; ++i)
00239 {
00240 seed.resize(my_test.kinematics_solver->getJointNames().size(), 0.0);
00241 fk_values.resize(my_test.kinematics_solver->getJointNames().size(), 0.0);
00242
00243 joint_state_group.setToRandomValues();
00244 joint_state_group.getGroupStateValues(fk_values);
00245
00246 std::vector<geometry_msgs::Pose> poses;
00247 poses.resize(1);
00248 bool result_fk = my_test.kinematics_solver->getPositionFK(fk_names, fk_values, poses);
00249 ASSERT_TRUE(result_fk);
00250
00251 bool result = my_test.kinematics_solver->searchPositionIK(poses[0], seed, timeout, solution, error_code);
00252 ROS_DEBUG("Pose: %f %f %f",poses[0].position.x, poses[0].position.y, poses[0].position.z);
00253 ROS_DEBUG("Orient: %f %f %f %f",poses[0].orientation.x, poses[0].orientation.y, poses[0].orientation.z, poses[0].orientation.w);
00254 if(result)
00255 {
00256 success++;
00257 result = my_test.kinematics_solver->getPositionIK(poses[0], solution, solution, error_code);
00258 EXPECT_TRUE(result);
00259 }
00260
00261 std::vector<geometry_msgs::Pose> new_poses;
00262 new_poses.resize(1);
00263 result_fk = my_test.kinematics_solver->getPositionFK(fk_names, solution, new_poses);
00264
00265 EXPECT_NEAR(poses[0].position.x, new_poses[0].position.x, IK_NEAR);
00266 EXPECT_NEAR(poses[0].position.y, new_poses[0].position.y, IK_NEAR);
00267 EXPECT_NEAR(poses[0].position.z, new_poses[0].position.z, IK_NEAR);
00268
00269 EXPECT_NEAR(poses[0].orientation.x, new_poses[0].orientation.x, IK_NEAR);
00270 EXPECT_NEAR(poses[0].orientation.y, new_poses[0].orientation.y, IK_NEAR);
00271 EXPECT_NEAR(poses[0].orientation.z, new_poses[0].orientation.z, IK_NEAR);
00272 EXPECT_NEAR(poses[0].orientation.w, new_poses[0].orientation.w, IK_NEAR);
00273 }
00274 ROS_INFO("Success Rate: %f",(double)success/total_tests);
00275 bool success_count = (success > 0.99*total_tests);
00276 EXPECT_TRUE(success_count);
00277 ROS_INFO("Elapsed time: %f", (ros::WallTime::now()-start_time).toSec());
00278 sleep(5.0);
00279 }
00280
00281 TEST(ArmIKPlugin, searchIKWithCallbacks)
00282 {
00283 rdf_loader::RDFLoader rdf_loader_;
00284 planning_models::RobotModelPtr kinematic_model;
00285 const boost::shared_ptr<srdf::Model> &srdf = rdf_loader_.getSRDF();
00286 const boost::shared_ptr<urdf::ModelInterface>& urdf_model = rdf_loader_.getURDF();
00287 robot_model.reset(new planning_models::RobotModel(urdf_model, srdf));
00288 planning_models::RobotModel::JointModelGroup* joint_model_group = kinematic_model->getJointModelGroup(my_test.kinematics_solver->getGroupName());
00289
00290
00291 std::vector<double> seed,fk_values,solution;
00292 double timeout = 5.0;
00293 moveit_msgs::MoveItErrorCodes error_code;
00294 solution.resize(my_test.kinematics_solver->getJointNames().size(), 0.0);
00295
00296 std::vector<std::string> fk_names;
00297 fk_names.push_back(my_test.kinematics_solver->getTipFrame());
00298
00299 planning_models::RobotState *kinematic_state(kinematic_model);
00300 planning_models::RobotState *::JointStateGroup joint_state_group(&kinematic_state,
00301 (const planning_models::RobotModel::JointModelGroup*) joint_model_group);
00302
00303 unsigned int num_tests = 0;
00304 unsigned int success = 0;
00305
00306 ros::NodeHandle nh("~");
00307 unsigned int number_ik_tests;
00308 nh.param("number_ik_tests_with_callbacks", number_ik_tests, 10);
00309 unsigned int success = 0;
00310
00311 for(unsigned int i=0; i < number_ik_tests; ++i)
00312 {
00313 seed.resize(my_test.kinematics_solver->getJointNames().size(), 0.0);
00314 fk_values.resize(my_test.kinematics_solver->getJointNames().size(), 0.0);
00315
00316 joint_state_group.setToRandomValues();
00317 joint_state_group.getGroupStateValues(fk_values);
00318
00319 std::vector<geometry_msgs::Pose> poses;
00320 poses.resize(1);
00321 bool result_fk = my_test.kinematics_solver->getPositionFK(fk_names, fk_values, poses);
00322 ASSERT_TRUE(result_fk);
00323 if(poses[0].position.z < 0.0)
00324 continue;
00325
00326 num_tests++;
00327 bool result = my_test.kinematics_solver->searchPositionIK(poses[0], seed, timeout, solution,
00328 boost::bind(&MyTest::pose_callback, &my_test, _1, _2, _3),
00329 boost::bind(&MyTest::joint_state_callback, &my_test, _1, _2, _3), error_code);
00330
00331 if(result)
00332 {
00333 success++;
00334 std::vector<geometry_msgs::Pose> new_poses;
00335 new_poses.resize(1);
00336 result_fk = my_test.kinematics_solver->getPositionFK(fk_names, solution, new_poses);
00337
00338 EXPECT_NEAR(poses[0].position.x, new_poses[0].position.x, IK_NEAR);
00339 EXPECT_NEAR(poses[0].position.y, new_poses[0].position.y, IK_NEAR);
00340 EXPECT_NEAR(poses[0].position.z, new_poses[0].position.z, IK_NEAR);
00341
00342 EXPECT_NEAR(poses[0].orientation.x, new_poses[0].orientation.x, IK_NEAR);
00343 EXPECT_NEAR(poses[0].orientation.y, new_poses[0].orientation.y, IK_NEAR);
00344 EXPECT_NEAR(poses[0].orientation.z, new_poses[0].orientation.z, IK_NEAR);
00345 EXPECT_NEAR(poses[0].orientation.w, new_poses[0].orientation.w, IK_NEAR);
00346 }
00347
00348 if(!ros::ok())
00349 break;
00350 }
00351 ROS_INFO("Success with callbacks (%%): %f",(double)success/num_tests);
00352 bool success_count = (success > 0.5*num_tests);
00353
00354 }
00355
00356
00357 int main(int argc, char **argv)
00358 {
00359 testing::InitGoogleTest(&argc, argv);
00360 ros::init (argc, argv, "right_arm_kinematics");
00361 return RUN_ALL_TESTS();
00362 }