00001
00028 #include <gtest/gtest.h>
00029 #include <ros/ros.h>
00030 #include "constrained_ik/constrained_ik.h"
00031 #include "constrained_ik/constraints/goal_pose.h"
00032 #include "constrained_ik/constraints/goal_position.h"
00033 #include "constrained_ik/constraints/goal_orientation.h"
00034 #include "constrained_ik/constraints/avoid_obstacles.h"
00035 #include "constrained_ik/constrained_ik_utils.h"
00036 #include <moveit/robot_model_loader/robot_model_loader.h>
00037 #include <moveit/robot_model/joint_model_group.h>
00038 #include <moveit/collision_plugin_loader/collision_plugin_loader.h>
00039 #include <boost/random/uniform_int_distribution.hpp>
00040
00041 using constrained_ik::Constrained_IK;
00042 using constrained_ik::basic_kin::BasicKin;
00043 using Eigen::Affine3d;
00044 using Eigen::VectorXd;
00045 using Eigen::MatrixXd;
00046 using Eigen::JacobiSVD;
00047
00048
00049 const std::string GROUP_NAME = "manipulator";
00050 const std::string ROBOT_DESCRIPTION_PARAM = "robot_description";
00053 TEST(constrained_ik, nullspaceprojection)
00054 {
00055 int rows = 6;
00056 int cols = 8;
00057 MatrixXd A = MatrixXd::Random(rows, cols);
00058
00059 JacobiSVD<MatrixXd> svd(A,Eigen::ComputeFullV | Eigen::ComputeFullU);
00060 MatrixXd V(svd.matrixV());
00061 MatrixXd U(svd.matrixU());
00062 Eigen::MatrixXd S(rows,cols);
00063
00064 for(int i=0; i<rows; i++)
00065 {
00066 for(int j=0; j<cols; j++) S(i,j) = 0.0;
00067 }
00068 VectorXd s = svd.singularValues();
00069 for(int i=0; i<rows-3; i++)
00070 {
00071 S(i,i) = s(i);
00072 }
00073
00074 MatrixXd A2 = U * S * V.transpose();
00075
00076 Constrained_IK CIK;
00077
00078 MatrixXd P1 = CIK.calcNullspaceProjectionTheRightWay(A2);
00079 EXPECT_EQ(P1.rows(), cols);
00080 EXPECT_EQ(P1.cols(), cols);
00081 MatrixXd P2 = CIK.calcNullspaceProjection(A2);
00082 EXPECT_EQ(P2.rows(), cols);
00083 EXPECT_EQ(P2.cols(), cols);
00084 VectorXd testv1 = VectorXd::Random(cols);
00085 VectorXd P1v = P1*testv1;
00086 VectorXd P2v = P2*testv1;
00087 VectorXd AP1v = A2*P1v;
00088 VectorXd AP2v = A2*P2v;
00089 double norm1 = AP1v.norm();
00090 double norm2 = AP2v.norm();
00091 EXPECT_LT(norm1, .00000001);
00092 EXPECT_LT(norm2, .00000001);
00093 }
00094
00099 class BasicIKTest : public ::testing::Test
00100 {
00101 protected:
00102
00103 robot_model_loader::RobotModelLoaderPtr loader_;
00104 moveit::core::RobotModelPtr robot_model_;
00105 planning_scene::PlanningScenePtr planning_scene_;
00106 BasicKin kin;
00107 Constrained_IK ik;
00108 Affine3d homePose;
00109 constrained_ik::ConstrainedIKConfiguration config;
00112 virtual void SetUp()
00113 {
00114 loader_.reset(new robot_model_loader::RobotModelLoader(ROBOT_DESCRIPTION_PARAM));
00115 robot_model_ = loader_->getModel();
00116
00117
00118 ASSERT_TRUE(robot_model_ != nullptr);
00119 ASSERT_TRUE(kin.init(robot_model_->getJointModelGroup(GROUP_NAME)));
00120 ASSERT_TRUE(kin.calcFwdKin(VectorXd::Zero(6), homePose));
00121 ASSERT_NO_THROW(ik.init(kin));
00122 ASSERT_NO_THROW(planning_scene_.reset(new planning_scene::PlanningScene(robot_model_)));
00123 ASSERT_NO_THROW(config = ik.getSolverConfiguration());
00124
00125
00126 collision_detection::CollisionPluginLoader cd_loader;
00127 std::string class_name = "IndustrialFCL";
00128 ASSERT_TRUE(cd_loader.activate(class_name, planning_scene_, true));
00129 }
00130 };
00131
00133 TEST_F(BasicIKTest, inputValidation)
00134 {
00135 EXPECT_ANY_THROW(Constrained_IK().init(BasicKin()));
00136 EXPECT_NO_THROW(Constrained_IK().init(kin));
00137
00138 EXPECT_EQ(Constrained_IK().checkInitialized(), constrained_ik::initialization_state::NothingInitialized);
00139 constrained_ik::Constraint *goal_ptr = new constrained_ik::constraints::GoalPosition();
00140 ik.addConstraint(goal_ptr, constrained_ik::constraint_types::Primary);
00141 EXPECT_NE(ik.checkInitialized(), constrained_ik::initialization_state::NothingInitialized);
00142 }
00143
00145 TEST_F(BasicIKTest, calcInvKinInputValidation)
00146 {
00147 VectorXd seed = VectorXd::Zero(6);
00148 VectorXd joints;
00149 constrained_ik::Constraint *goal_ptr = new constrained_ik::constraints::GoalPosition();
00150 ik.addConstraint(goal_ptr, constrained_ik::constraint_types::Primary);
00151 EXPECT_NE(ik.checkInitialized(), constrained_ik::initialization_state::NothingInitialized);
00152 EXPECT_ANY_THROW(Constrained_IK().calcInvKin(Affine3d::Identity(), seed, joints));
00153 EXPECT_ANY_THROW(ik.calcInvKin(Affine3d(Eigen::Matrix4d::Zero()), seed, joints));
00154 EXPECT_ANY_THROW(ik.calcInvKin(homePose, VectorXd(), joints));
00155 EXPECT_ANY_THROW(ik.calcInvKin(homePose, VectorXd::Zero(99), joints));
00156
00157
00158
00159 try
00160 {
00161 ik.calcInvKin(homePose, seed, joints);
00162 SUCCEED();
00163 } catch (const std::exception &ex)
00164 {
00165 ADD_FAILURE() << ex.what();
00166 }
00167 }
00168
00170 TEST_F(BasicIKTest, knownPoses)
00171 {
00172 Affine3d pose, rslt_pose;
00173 VectorXd seed, expected(6), joints;
00174 ik.loadDefaultSolverConfiguration();
00175 config = ik.getSolverConfiguration();
00176
00177
00178 expected << M_PI_2, -M_PI_2, -M_PI_2, -M_PI_2, M_PI_2, -M_PI_2;
00179 seed = expected;
00180 EXPECT_TRUE(kin.calcFwdKin(expected, pose));
00181
00182 std::cout << "Testing seed vector " << seed.transpose() << std::endl <<
00183 "*at* from expected: " << expected.transpose() << std::endl;
00184
00185
00186 ik.clearConstraintList();
00187 constrained_ik::Constraint *goal_pose_ptr = new constrained_ik::constraints::GoalPose();
00188 ik.addConstraint(goal_pose_ptr, constrained_ik::constraint_types::Primary);
00189
00190
00191 EXPECT_NO_THROW(ik.calcInvKin(pose, seed, joints));
00192 std::cout << "joint values returned" << joints << std::endl;
00193 EXPECT_TRUE(joints.isApprox(expected, 1e-10));
00194
00195
00196 seed = expected + 0.01 * VectorXd::Random(expected.size());
00197 std::cout << "Testing seed vector " << seed.transpose() << std::endl <<
00198 "*near* from expected: " << expected.transpose() << std::endl;
00199 EXPECT_TRUE(ik.calcInvKin(pose, seed, joints));
00200 EXPECT_TRUE(kin.calcFwdKin(joints, rslt_pose));
00201 EXPECT_TRUE(rslt_pose.rotation().isApprox(pose.rotation(), 9e-3));
00202 EXPECT_TRUE(rslt_pose.translation().isApprox(pose.translation(), 1e-3));
00203
00204
00205 seed = expected + 0.05 * VectorXd::Random(expected.size());
00206 std::cout << "Testing seed vector " << seed.transpose() << std::endl <<
00207 "*near* from expected: " << expected.transpose() << std::endl;
00208 EXPECT_TRUE(ik.calcInvKin(pose, seed, joints));
00209 EXPECT_TRUE(kin.calcFwdKin(joints, rslt_pose));
00210 EXPECT_TRUE(rslt_pose.rotation().isApprox(pose.rotation(), 9e-3));
00211 EXPECT_TRUE(rslt_pose.translation().isApprox(pose.translation(), 1e-3));
00212
00213
00214 seed = expected + 0.1 * VectorXd::Random(expected.size());
00215 std::cout << "Testing seed vector " << seed.transpose() << std::endl <<
00216 "*near* from expected: " << expected.transpose() << std::endl;
00217 EXPECT_TRUE(ik.calcInvKin(pose, seed, joints));
00218 EXPECT_TRUE(kin.calcFwdKin(joints, rslt_pose));
00219 EXPECT_TRUE(rslt_pose.rotation().isApprox(pose.rotation(), 9e-3));
00220 EXPECT_TRUE(rslt_pose.translation().isApprox(pose.translation(), 1e-3));
00221
00222
00223 expected << M_PI_2, 0, 0, 0, 0, 0;
00224 kin.calcFwdKin(expected, pose);
00225 std::cout << "Testing seed vector " << VectorXd::Zero(expected.size()).transpose() << std::endl <<
00226 "*far1* from expected: " << expected.transpose() << std::endl;
00227 config.primary_gain = 0.5;
00228 config.limit_primary_motion = false;
00229 ik.setSolverConfiguration(config);
00230 EXPECT_TRUE(ik.calcInvKin(pose, VectorXd::Zero(expected.size()), joints));
00231 EXPECT_TRUE(kin.calcFwdKin(joints, rslt_pose));
00232 EXPECT_TRUE(rslt_pose.rotation().isApprox(pose.rotation(), 9e-3));
00233 EXPECT_TRUE(rslt_pose.translation().isApprox(pose.translation(), 1e-3));
00234
00235
00236 expected << 0, -M_PI_2, 0, 0, 0, 0;
00237 kin.calcFwdKin(expected, pose);
00238 std::cout << "Testing seed vector " << VectorXd::Zero(expected.size()).transpose() << std::endl <<
00239 "*far2* from expected: " << expected.transpose() << std::endl;
00240 EXPECT_TRUE(ik.calcInvKin(pose, VectorXd::Zero(expected.size()), joints));
00241 EXPECT_TRUE(kin.calcFwdKin(joints, rslt_pose));
00242 EXPECT_TRUE(rslt_pose.rotation().isApprox(pose.rotation(), 9e-3));
00243 EXPECT_TRUE(rslt_pose.translation().isApprox(pose.translation(), 1e-3));
00244
00245
00246 expected << M_PI_4, -M_PI_4, 0, 0, 0, 0;
00247 kin.calcFwdKin(expected, pose);
00248 std::cout << "Testing seed vector " << VectorXd::Zero(expected.size()).transpose() << std::endl <<
00249 "*farther* from expected: " << expected.transpose() << std::endl;
00250 seed = VectorXd::Zero(expected.size());
00251 EXPECT_TRUE(ik.calcInvKin(pose, seed, joints));
00252 EXPECT_TRUE(kin.calcFwdKin(joints, rslt_pose));
00253 EXPECT_TRUE(rslt_pose.rotation().isApprox(pose.rotation(), 9e-3));
00254 EXPECT_TRUE(rslt_pose.translation().isApprox(pose.translation(), 1e-3));
00255
00256
00257 expected << M_PI_2, -M_PI_2, 0, 0, 0, 0;
00258 kin.calcFwdKin(expected, pose);
00259 std::cout << "Testing seed vector " << VectorXd::Zero(expected.size()).transpose() << std::endl <<
00260 "*very far* from expected: " << expected.transpose() << std::endl;
00261 seed = VectorXd::Zero(expected.size());
00262 EXPECT_TRUE(ik.calcInvKin(pose, seed, joints));
00263 EXPECT_TRUE(kin.calcFwdKin(joints, rslt_pose));
00264 EXPECT_TRUE(rslt_pose.rotation().isApprox(pose.rotation(), 9e-3));
00265 EXPECT_TRUE(rslt_pose.translation().isApprox(pose.translation(), 1e-3));
00266 }
00267
00269 TEST_F(BasicIKTest, NullMotion)
00270 {
00271 Affine3d pose, rslt_pose;
00272 VectorXd seed, expected(6), joints;
00273 boost::random::mt19937 rng;
00274 ik.loadDefaultSolverConfiguration();
00275 config = ik.getSolverConfiguration();
00276 config.limit_auxiliary_interations = false;
00277 config.limit_auxiliary_motion = false;
00278 config.limit_primary_motion = false;
00279 ik.setSolverConfiguration(config);
00280
00281
00282 ik.clearConstraintList();
00283 constrained_ik::Constraint *goal_position_ptr = new constrained_ik::constraints::GoalPosition();
00284 ik.addConstraint(goal_position_ptr, constrained_ik::constraint_types::Primary);
00285 constrained_ik::Constraint *goal_orientation_ptr = new constrained_ik::constraints::GoalOrientation();
00286 ik.addConstraint(goal_orientation_ptr, constrained_ik::constraint_types::Auxiliary);
00287
00288
00289 expected << M_PI_2, -M_PI_2, -M_PI_2, -M_PI_2, M_PI_2, -M_PI_2;
00290
00291 kin.calcFwdKin(expected, pose);
00292 config.primary_gain = 0.5;
00293 config.auxiliary_gain = 0.5;
00294 ik.setSolverConfiguration(config);
00295 seed = expected;
00296 std::cout << "Testing seed vector " << seed.transpose() << std::endl <<
00297 "*at* from expected: " << expected.transpose() << std::endl;
00298 ik.calcInvKin(pose, seed, joints);
00299 EXPECT_TRUE(joints.isApprox(expected, 1e-10));
00300
00301
00302 expected << M_PI_2, -M_PI_2, -M_PI_2, -M_PI_2, M_PI_2, -M_PI_2;
00303 kin.calcFwdKin(expected, pose);
00304 seed = expected + 0.01 * VectorXd::Random(expected.size());
00305 std::cout << "Testing seed vector " << seed.transpose() << std::endl <<
00306 "*near* from expected: " << expected.transpose() << std::endl;
00307 EXPECT_TRUE(ik.calcInvKin(pose, seed, joints));
00308 EXPECT_TRUE(kin.calcFwdKin(joints, rslt_pose));
00309 EXPECT_TRUE(rslt_pose.rotation().isApprox(pose.rotation(), 9e-3));
00310 EXPECT_TRUE(rslt_pose.translation().isApprox(pose.translation(), 1e-3));
00311
00312
00313 for(int j=0; j<3; j++)
00314 {
00315 for(int i=0; i<6; i++)
00316 {
00317 boost::random::uniform_int_distribution<int> angle_degrees(-177, 177) ;
00318 boost::random::uniform_int_distribution<int> small_angle_degrees(-3, 3) ;
00319 expected[i] = angle_degrees(rng)* 3.14/180.0;
00320 seed[i] = expected[i] + small_angle_degrees(rng)*3.14/180.0;
00321 }
00322 kin.calcFwdKin(expected, pose);
00323 config.primary_gain = 0.15;
00324 config.auxiliary_gain = 0.05;
00325 ik.setSolverConfiguration(config);
00326 EXPECT_TRUE(ik.calcInvKin(pose, seed, joints));
00327 EXPECT_TRUE(kin.calcFwdKin(joints, rslt_pose));
00328 EXPECT_TRUE(rslt_pose.rotation().isApprox(pose.rotation(), 9e-3));
00329 EXPECT_TRUE(rslt_pose.translation().isApprox(pose.translation(), 1e-3));
00330 }
00331
00332
00333 int num_success=0;
00334 for(int j=0; j<20; j++)
00335 {
00336 for(int i=0; i<6; i++)
00337 {
00338 boost::random::uniform_int_distribution<int> angle_degrees(-180+50, 180-50) ;
00339 boost::random::uniform_int_distribution<int> small_angle_degrees(-50, 50) ;
00340 expected[i] = angle_degrees(rng)* 3.14/180.0;
00341 seed[i] = expected[i] + small_angle_degrees(rng)*3.14/180.0;
00342 }
00343 kin.calcFwdKin(expected, pose);
00344 config.primary_gain = 0.15;
00345 config.auxiliary_gain = 0.05;
00346 ik.setSolverConfiguration(config);
00347 ik.calcInvKin(pose, seed, joints);
00348 kin.calcFwdKin(joints, rslt_pose);
00349 if(rslt_pose.rotation().isApprox(pose.rotation(), 9e-3) && rslt_pose.translation().isApprox(pose.translation(), 1e-3)) num_success++;
00350 }
00351 EXPECT_GE(num_success, 15);
00352
00353
00354 num_success=0;
00355 for(int j=0; j<20; j++)
00356 {
00357 for(int i=0; i<6; i++)
00358 {
00359 boost::random::uniform_int_distribution<int> angle_degrees(-180+90, 180-90) ;
00360 boost::random::uniform_int_distribution<int> small_angle_degrees(-90, 90) ;
00361 expected[i] = angle_degrees(rng)* 3.14/180.0;
00362 seed[i] = expected[i] + small_angle_degrees(rng)*3.14/180.0;
00363 }
00364 kin.calcFwdKin(expected, pose);
00365 config.primary_gain = 0.15;
00366 config.auxiliary_gain = 0.05;
00367 ik.setSolverConfiguration(config);
00368 ik.calcInvKin(pose, seed, joints);
00369 kin.calcFwdKin(joints, rslt_pose);
00370 if(rslt_pose.rotation().isApprox(pose.rotation(), 9e-3) && rslt_pose.translation().isApprox(pose.translation(), 1e-3)) num_success++;
00371 }
00372 EXPECT_GE(num_success, 10);
00373 }
00374
00376 TEST_F(BasicIKTest, NullMotionPose)
00377 {
00378 Affine3d pose, rslt_pose;
00379 VectorXd seed, expected(6), joints;
00380 ik.loadDefaultSolverConfiguration();
00381 config = ik.getSolverConfiguration();
00382
00383
00384 ik.clearConstraintList();
00385 constrained_ik::Constraint *goal_orientation_ptr = new constrained_ik::constraints::GoalOrientation();
00386 ik.addConstraint(goal_orientation_ptr, constrained_ik::constraint_types::Primary);
00387 constrained_ik::Constraint *goal_position_ptr = new constrained_ik::constraints::GoalPosition();
00388 ik.addConstraint(goal_position_ptr, constrained_ik::constraint_types::Auxiliary);
00389
00390
00391 expected << M_PI_2, -M_PI_2, -M_PI_2, -M_PI_2, M_PI_2, -M_PI_2;
00392 kin.calcFwdKin(expected, pose);
00393 seed = expected;
00394 std::cout << "Testing seed vector " << seed.transpose() << std::endl <<
00395 "*at* from expected: " << expected.transpose() << std::endl;
00396 EXPECT_TRUE(ik.calcInvKin(pose, seed, joints));
00397 EXPECT_TRUE(kin.calcFwdKin(joints, rslt_pose));
00398 EXPECT_TRUE(rslt_pose.rotation().isApprox(pose.rotation(), 9e-3));
00399 EXPECT_TRUE(rslt_pose.translation().isApprox(pose.translation(), 1e-3));
00400
00401
00402 seed = expected + 0.01 * VectorXd::Random(expected.size());
00403 std::cout << "Testing seed vector " << seed.transpose() << std::endl <<
00404 "*near* expected: " << expected.transpose() << std::endl;
00405 EXPECT_TRUE(ik.calcInvKin(pose, seed, joints));
00406 EXPECT_TRUE(kin.calcFwdKin(joints, rslt_pose));
00407 EXPECT_TRUE(rslt_pose.rotation().isApprox(pose.rotation(), 9e-3));
00408 EXPECT_TRUE(rslt_pose.translation().isApprox(pose.translation(), 1e-3));
00409
00410 seed = expected + 0.05 * VectorXd::Random(expected.size());
00411 std::cout << "Testing seed vector " << seed.transpose() << std::endl <<
00412 "*near* expected: " << expected.transpose() << std::endl;
00413 EXPECT_TRUE(ik.calcInvKin(pose, seed, joints));
00414 EXPECT_TRUE(kin.calcFwdKin(joints, rslt_pose));
00415 EXPECT_TRUE(rslt_pose.rotation().isApprox(pose.rotation(), 9e-3));
00416 EXPECT_TRUE(rslt_pose.translation().isApprox(pose.translation(), 1e-3));
00417
00418
00419 seed = expected + 0.1 * VectorXd::Random(expected.size());
00420 std::cout << "Testing seed vector " << seed.transpose() << std::endl <<
00421 "*near* from expected: " << expected.transpose() << std::endl;
00422 EXPECT_TRUE(ik.calcInvKin(pose, seed, joints));
00423 EXPECT_TRUE(kin.calcFwdKin(joints, rslt_pose));
00424 EXPECT_TRUE(rslt_pose.rotation().isApprox(pose.rotation(), 9e-3));
00425 EXPECT_TRUE(rslt_pose.translation().isApprox(pose.translation(), 1e-3));
00426
00427
00428 expected << M_PI_2, 0, 0, 0, 0, 0;
00429 kin.calcFwdKin(expected, pose);
00430 std::cout << "Testing seed vector " << VectorXd::Zero(expected.size()).transpose() << std::endl <<
00431 "*far1* from expected: " << expected.transpose() << std::endl;
00432 config.primary_gain = 0.1;
00433 config.auxiliary_gain = 0.1;
00434 config.limit_auxiliary_interations = false;
00435 config.limit_auxiliary_motion = false;
00436 config.limit_primary_motion = false;
00437 ik.setSolverConfiguration(config);
00438 seed = VectorXd::Zero(expected.size());
00439 EXPECT_TRUE(ik.calcInvKin(pose, seed, joints));
00440 EXPECT_TRUE(kin.calcFwdKin(joints, rslt_pose));
00441 EXPECT_TRUE(rslt_pose.rotation().isApprox(pose.rotation(), 9e-3));
00442 EXPECT_TRUE(rslt_pose.translation().isApprox(pose.translation(), 1e-3));
00443
00444
00445 expected << 0, -M_PI_2, 0, 0, 0, 0;
00446 kin.calcFwdKin(expected, pose);
00447 std::cout << "Testing seed vector " << VectorXd::Zero(expected.size()).transpose() << std::endl <<
00448 "*far2* from expected: " << expected.transpose() << std::endl;
00449 seed = VectorXd::Zero(expected.size());
00450 EXPECT_TRUE(ik.calcInvKin(pose, seed, joints));
00451 EXPECT_TRUE(kin.calcFwdKin(joints, rslt_pose));
00452 EXPECT_TRUE(rslt_pose.rotation().isApprox(pose.rotation(), 9e-3));
00453 EXPECT_TRUE(rslt_pose.translation().isApprox(pose.translation(), 1e-3));
00454
00455
00456 expected << M_PI_4, -M_PI_4, 0, 0, 0, 0;
00457 kin.calcFwdKin(expected, pose);
00458 std::cout << "Testing seed vector " << VectorXd::Zero(expected.size()).transpose() << std::endl <<
00459 "*farther* from expected: " << expected.transpose() << std::endl;
00460 seed = VectorXd::Zero(expected.size());
00461 EXPECT_TRUE(ik.calcInvKin(pose, seed, joints));
00462 EXPECT_TRUE(kin.calcFwdKin(joints, rslt_pose));
00463 EXPECT_TRUE(rslt_pose.rotation().isApprox(pose.rotation(), 9e-3));
00464 EXPECT_TRUE(rslt_pose.translation().isApprox(pose.translation(), 1e-3));
00465
00466
00467 expected << M_PI_2, -M_PI_2, 0, 0, 0, 0;
00468 kin.calcFwdKin(expected, pose);
00469 std::cout << "Testing seed vector " << VectorXd::Zero(expected.size()).transpose() << std::endl <<
00470 "*very far* from expected: " << expected.transpose() << std::endl;
00471 config.primary_gain = 0.1;
00472 config.auxiliary_gain = 0.001;
00473 config.solver_max_iterations = 10000;
00474 ik.setSolverConfiguration(config);
00475 seed = VectorXd::Zero(expected.size());
00476 EXPECT_TRUE(ik.calcInvKin(pose, seed, joints));
00477 EXPECT_TRUE(kin.calcFwdKin(joints, rslt_pose));
00478 EXPECT_TRUE(rslt_pose.rotation().isApprox(pose.rotation(), 9e-3));
00479 EXPECT_TRUE(rslt_pose.translation().isApprox(pose.translation(), 1e-3));
00480 }
00481
00491 TEST_F(BasicIKTest, obstacleAvoidanceAuxiliaryConstraint)
00492 {
00493 Affine3d pose, rslt_pose;
00494 VectorXd seed, expected(6), joints;
00495 ik.loadDefaultSolverConfiguration();
00496 config = ik.getSolverConfiguration();
00497 config.solver_min_iterations = 1;
00498 config.limit_auxiliary_interations = true;
00499 ik.setSolverConfiguration(config);
00500
00501
00502 ik.clearConstraintList();
00503 constrained_ik::Constraint *goal_position_ptr = new constrained_ik::constraints::GoalPosition();
00504
00505 std::vector<std::string> link_names;
00506 ik.getLinkNames(link_names);
00507 int link_id = link_names.size()/2;
00508 std::vector<std::string> obstacle_avoidance_link_name;
00509 constrained_ik::constraints::AvoidObstacles *avoid_obstacles_ptr = new constrained_ik::constraints::AvoidObstacles();
00510
00511 obstacle_avoidance_link_name.push_back(link_names[link_id]);
00512 avoid_obstacles_ptr->setAvoidanceLinks(obstacle_avoidance_link_name);
00513 avoid_obstacles_ptr->setMinDistance(link_names[link_id], 0.01);
00514 avoid_obstacles_ptr->setAmplitude(link_names[link_id], 1.0);
00515 avoid_obstacles_ptr->setAvoidanceDistance(link_names[link_id], 1.0);
00516
00517
00518 ik.addConstraint(goal_position_ptr, constrained_ik::constraint_types::Primary);
00519 ik.addConstraint(avoid_obstacles_ptr, constrained_ik::constraint_types::Auxiliary);
00520
00521
00522 expected << M_PI_2, -M_PI_2, -M_PI_2, -M_PI_2, M_PI_2, -M_PI_2;
00523 kin.calcFwdKin(expected, pose);
00524 seed = expected;
00525 config.auxiliary_max_iterations = 1;
00526 ik.setSolverConfiguration(config);
00527 EXPECT_TRUE(ik.calcInvKin(pose, seed, planning_scene_, joints));
00528 EXPECT_TRUE(kin.calcFwdKin(joints,rslt_pose));
00529 EXPECT_TRUE(rslt_pose.translation().isApprox(pose.translation(), 1e-3));
00530 EXPECT_NE(expected, joints);
00531
00532
00533
00534 config.auxiliary_max_iterations = 100;
00535 ik.setSolverConfiguration(config);
00536 EXPECT_TRUE(ik.calcInvKin(pose, seed, planning_scene_, joints));
00537 EXPECT_TRUE(kin.calcFwdKin(joints,rslt_pose));
00538 EXPECT_TRUE(rslt_pose.translation().isApprox(pose.translation(), 1e-3));
00539 EXPECT_NE(expected, joints);
00540 }
00541
00546 TEST_F(BasicIKTest, consistancy)
00547 {
00548 Eigen::Vector3d k(Eigen::Vector3d::UnitZ());
00549 for (double theta=-7.0; theta<7.0; theta+=1.0)
00550 {
00551 Eigen::Vector4d expected; expected << k, ik.rangedAngle(theta);
00552
00553
00554 Eigen::AngleAxisd aa(theta, k);
00555 Eigen::Quaterniond q(aa);
00556 Eigen::AngleAxisd aa_q(q);
00557
00558
00559 Eigen::Vector4d rslt; rslt << aa_q.axis(), aa_q.angle();
00560 rslt(3) = ik.rangedAngle(aa_q.angle());
00561
00562
00563 if (fabs(theta) < 1e-6)
00564 {
00565 expected(0) = 1;
00566 expected(1) = 0;
00567 expected(2) = 0;
00568 }
00569
00570
00571 EXPECT_TRUE(rslt.isApprox(expected, 1e-5) or rslt.isApprox(-expected, 1e-5));
00572 }
00573 }
00575 int main(int argc, char **argv)
00576 {
00577 testing::InitGoogleTest(&argc, argv);
00578 ros::init(argc,argv,"test_constrained_ik");
00579 ros::NodeHandle nh;
00580 return RUN_ALL_TESTS();
00581 }
00582