test_BasicKin.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (Apache License)
00003  *
00004  * Copyright (c) 2013, Southwest Research Institute
00005  *
00006  * Licensed under the Apache License, Version 2.0 (the "License");
00007  * you may not use this file except in compliance with the License.
00008  * You may obtain a copy of the License at
00009  *
00010  *   http://www.apache.org/licenses/LICENSE-2.0
00011  *
00012  * Unless required by applicable law or agreed to in writing, software
00013  * distributed under the License is distributed on an "AS IS" BASIS,
00014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  * See the License for the specific language governing permissions and
00016  * limitations under the License.
00017  */
00018 
00019 #include <gtest/gtest.h>
00020 #include <constrained_ik/basic_kin.h>
00021 #include <boost/assign/list_of.hpp>
00022 #include <eigen_conversions/eigen_kdl.h>
00023 
00024 using constrained_ik::basic_kin::BasicKin;
00025 using Eigen::MatrixXd;
00026 using Eigen::VectorXd;
00027 
00028 /* ----------------------------------------------------------------
00029  * Test Fixtures
00030  *   consolidate variable-definitions and init functions
00031  *   for use by multiple tests.
00032  * ----------------------------------------------------------------
00033  */
00034 class BaseTest : public :: testing::Test
00035 {
00036 protected:
00037   BasicKin kin;
00038 };
00039 
00040 class RobotTest : public BaseTest
00041 {
00042 protected:
00043   urdf::Model model;
00044 
00045   virtual void SetUp()
00046   {
00047     ASSERT_TRUE(model.initFile(urdf_file));
00048     ASSERT_TRUE(kin.init(model, "base_link", "link_6"));
00049   }
00050 
00051   bool comparePoses(const std::vector<KDL::Frame> &actual, const std::vector<KDL::Frame> &expected, const double tol = 1e-6)
00052   {
00053       bool rtn;
00054 //      ASSERT_TRUE(actual.size() == expected.size());
00055       if (actual.size() != expected.size())
00056           return false;
00057       for (size_t ii=0; ii<actual.size(); ++ii)
00058       {
00059           if (!KDL::Equal(actual[ii], expected[ii], tol))
00060               return false;
00061       }
00062       return true;
00063   }
00064 
00065 private:
00066   static const std::string urdf_file;
00067 };
00068 const std::string RobotTest::urdf_file = "puma_560.urdf";
00069 
00070 class PInvTest : public BaseTest
00071 {
00072 protected:
00073   bool test_random(int rows, int cols)
00074   {
00075     MatrixXd A = MatrixXd::Random(rows, cols);
00076     VectorXd x = VectorXd::Random(cols);
00077     VectorXd b = A*x;
00078     VectorXd rslt;
00079 
00080     bool status = kin.solvePInv(A, b, rslt);
00081     return status && rslt.isApprox(x, 1e-10);
00082   }
00083 };
00084 
00085 typedef RobotTest init;
00086 typedef RobotTest calcFwdKin;
00087 typedef RobotTest calcJacobian;
00088 typedef RobotTest linkTransforms;
00089 typedef PInvTest  solvePInv;
00090 /* ---------------------------------------------------------------- */
00091 
00092 TEST_F(init, inputValidation)
00093 {
00094   EXPECT_FALSE(kin.init(urdf::Model(), "base_link", "tip_link"));
00095   EXPECT_FALSE(kin.init(model, "", ""));
00096   EXPECT_FALSE(kin.init(model, "base_link", ""));
00097   EXPECT_FALSE(kin.init(model, "", "link_6"));
00098   EXPECT_FALSE(kin.init(model, "INVALID", "link_6"));
00099   EXPECT_FALSE(kin.init(model, "base_link", "INVALID"));
00100   EXPECT_TRUE(kin.init(model, "base_link", "link_6"));
00101 }
00102 
00103 
00104 TEST_F(linkTransforms, inputValidation)
00105 {
00106     std::vector<std::string> link_names = boost::assign::list_of("link_1")("link_2")("link_3")("link_4")("link_5")("link_6");
00107     std::vector<KDL::Frame> poses;
00108 
00109     EXPECT_FALSE(BasicKin().linkTransforms(VectorXd(), poses));                                     // un-init BasicKin, names, & Jnts
00110     EXPECT_FALSE(BasicKin().linkTransforms(VectorXd(), poses, std::vector<std::string>()));         // un-init BasicKin, names, & Jnts
00111     EXPECT_FALSE(BasicKin().linkTransforms(VectorXd(), poses, link_names));                         // un-init BasicKin & Jnts
00112     EXPECT_FALSE(BasicKin().linkTransforms(VectorXd::Zero(6), poses, std::vector<std::string>()));  // un-init BasicKin & names
00113     EXPECT_FALSE(BasicKin().linkTransforms(VectorXd::Zero(6), poses, link_names));                  // un-init BasicKin
00114 
00115     EXPECT_FALSE(kin.linkTransforms(VectorXd(), poses, std::vector<std::string>()));                // empty names & joints
00116     EXPECT_FALSE(kin.linkTransforms(VectorXd::Zero(99), poses, link_names));                        // too many joints
00117     EXPECT_FALSE(kin.linkTransforms(VectorXd::Constant(6, 1e10), poses, link_names));               // joints out-of-range
00118 
00119     EXPECT_TRUE(kin.linkTransforms(VectorXd::Zero(6), poses, link_names));                          // valid input
00120     EXPECT_TRUE(kin.linkTransforms(VectorXd::Zero(6), poses));                                      // valid input
00121 
00122     std::vector<std::string> link_names_short = boost::assign::list_of(link_names[5]);
00123     EXPECT_TRUE(kin.linkTransforms(VectorXd::Zero(6), poses, link_names_short));                    //valid short input
00124 
00125     link_names[5] = "fail_on_this";
00126     EXPECT_FALSE(kin.linkTransforms(VectorXd::Zero(6), poses, link_names));                         // invalid link list
00127     link_names_short[0] = link_names[5];
00128     EXPECT_FALSE(kin.linkTransforms(VectorXd::Zero(6), poses, link_names_short));                   // invalid & short link list
00129 }
00130 
00131 
00132 TEST_F(linkTransforms, knownPoses)
00133 {
00134     using KDL::Rotation;
00135     using KDL::Vector;
00136     using KDL::Frame;
00137 
00138     std::vector<std::string> link_names = boost::assign::list_of("link_1")("link_2")("link_3")("link_4")("link_5")("link_6");
00139     VectorXd joint_angles(6);
00140     std::vector<Frame> actual, expected(6);
00141 
00142     //0,0,0,0,0,0
00143     joint_angles = VectorXd::Zero(6);
00144     expected[0] = Frame(Vector(0,0,.674));              //rotation defaults to identity
00145     expected[1] = Frame(Vector(0,0,.674));              //rotation defaults to identity
00146     expected[2] = Frame(Vector(.4318,.12446,.674));     //rotation defaults to identity
00147     expected[3] = Frame(Vector(.41148,.12446,1.1058));  //rotation defaults to identity
00148     expected[4] = Frame(Vector(.41148,.12446,1.1058));  //rotation defaults to identity
00149     expected[5] = Frame(Vector(.41148,.12446,1.1058));  //rotation defaults to identity
00150     EXPECT_TRUE(kin.linkTransforms(joint_angles, actual, link_names));  //all link names
00151     EXPECT_TRUE(comparePoses(actual, expected, 1e-4));
00152     EXPECT_TRUE(kin.linkTransforms(joint_angles, actual));              //no link names (defaults to all)
00153     EXPECT_TRUE(comparePoses(actual, expected, 1e-4));
00154 
00155     //90,0,0,0,0,0
00156     joint_angles(0) = M_PI_2;
00157     expected[0] = Frame(Rotation(0,-1,0,1,0,0,0,0,1), Vector(0,0,.674));
00158     expected[1] = Frame(Rotation(0,-1,0,1,0,0,0,0,1), Vector(0,0,.674));
00159     expected[2] = Frame(Rotation(0,-1,0,1,0,0,0,0,1), Vector(-.12446,.4318,.674));
00160     expected[3] = Frame(Rotation(0,-1,0,1,0,0,0,0,1), Vector(-.12446,.41148,1.1058));
00161     expected[4] = Frame(Rotation(0,-1,0,1,0,0,0,0,1), Vector(-.12446,.41148,1.1058));
00162     expected[5] = Frame(Rotation(0,-1,0,1,0,0,0,0,1), Vector(-.12446,.41148,1.1058));
00163     EXPECT_TRUE(kin.linkTransforms(joint_angles, actual, link_names));  //all link names
00164     EXPECT_TRUE(comparePoses(actual, expected, 1e-4));
00165     EXPECT_TRUE(kin.linkTransforms(joint_angles, actual));              //no link names (defaults to all)
00166     EXPECT_TRUE(comparePoses(actual, expected, 1e-4));
00167 
00168     //0,-90,0,0,0,0
00169     joint_angles(0) = 0.;
00170     joint_angles(1) = -M_PI_2;
00171     expected[0] = Frame(Vector(0,0,.674));
00172     expected[1] = Frame(Rotation(0,0,-1,0,1,0,1,0,0), Vector(0,0,.674));
00173     expected[2] = Frame(Rotation(0,0,-1,0,1,0,1,0,0), Vector(0, .12446,1.1058));
00174     expected[3] = Frame(Rotation(0,0,-1,0,1,0,1,0,0), Vector(-.4318,.12446,1.08548));
00175     expected[4] = Frame(Rotation(0,0,-1,0,1,0,1,0,0), Vector(-.4318,.12446,1.08548));
00176     expected[5] = Frame(Rotation(0,0,-1,0,1,0,1,0,0), Vector(-.4318,.12446,1.08548));
00177     EXPECT_TRUE(kin.linkTransforms(joint_angles, actual, link_names));  //all link names
00178     EXPECT_TRUE(comparePoses(actual, expected, 1e-4));
00179     EXPECT_TRUE(kin.linkTransforms(joint_angles, actual));              //no link names (defaults to all)
00180     EXPECT_TRUE(comparePoses(actual, expected, 1e-4));
00181 
00182     //joints 2-5
00183     joint_angles = VectorXd::Zero(6);
00184     std::vector<std::string> link_names_short(link_names.begin()+1, link_names.end()-1);
00185 //    expected[0] = Frame(Vector(0,0,.674));    //rotation defaults to identity
00186     expected[1] = Frame(Vector(0,0,.674));    //rotation defaults to identity
00187     expected[2] = Frame(Vector(.4318,.12446,.674));     //rotation defaults to identity
00188     expected[3] = Frame(Vector(.41148,.12446,1.1058));  //rotation defaults to identity
00189     expected[4] = Frame(Vector(.41148,.12446,1.1058));  //rotation defaults to identity
00190 //    expected[5] = Frame(Vector(.41148,.12446,1.1058));  //rotation defaults to identity
00191     std::vector<Frame> expected_short(expected.begin()+1, expected.end()-1);
00192     EXPECT_TRUE(kin.linkTransforms(joint_angles, actual, link_names_short));    //all link names
00193     EXPECT_TRUE(comparePoses(actual, expected_short, 1e-4));
00194     EXPECT_TRUE(kin.linkTransforms(joint_angles, actual));                      //no link names (defaults to all)
00195     EXPECT_FALSE(comparePoses(actual, expected, 1e-4));
00196 }
00197 
00198 
00199 TEST_F(calcFwdKin, inputValidation)
00200 {
00201     //test for calcFwdKin(joints, pose)
00202   Eigen::Affine3d pose;
00203 
00204   EXPECT_FALSE(BasicKin().calcFwdKin(VectorXd(), pose));            // un-init BasicKin & Jnts
00205   EXPECT_FALSE(BasicKin().calcFwdKin(VectorXd::Zero(6), pose));     // un-init BasicKin
00206   EXPECT_FALSE(kin.calcFwdKin(VectorXd(), pose));                   // empty joints
00207   EXPECT_FALSE(kin.calcFwdKin(VectorXd::Zero(99), pose));           // too many joints
00208   EXPECT_FALSE(kin.calcFwdKin(VectorXd::Constant(6, 1e10), pose));  // joints out-of-range
00209 
00210   EXPECT_TRUE(kin.calcFwdKin(VectorXd::Zero(6), pose));             // valid input
00211 }
00212 
00213 
00214 TEST_F(calcFwdKin, knownPoses)
00215 {
00216   VectorXd joints = VectorXd::Zero(6);
00217   Eigen::Affine3d expected, result;
00218 
00219   // all joints 0
00220   EXPECT_TRUE(kin.calcFwdKin(joints, result));
00221   expected = Eigen::Translation3d(0.41148, 0.12446, 1.1058);
00222   EXPECT_TRUE(result.isApprox(expected, 1e-3));
00223 
00224   // 1st joint 90 deg,all others 0
00225   joints(0) = M_PI_2;
00226   EXPECT_TRUE(kin.calcFwdKin(joints, result));
00227   expected = Eigen::Translation3d(-0.12446, 0.41148, 1.1058);
00228   expected.rotate(Eigen::AngleAxis<double> (M_PI_2, Eigen::Vector3d(0,0,1)));
00229   EXPECT_TRUE(result.isApprox(expected, 1e-3));
00230 
00231   // 2nd joint -90, all others 0
00232   joints(0) = 0.0;
00233   joints(1) = -M_PI_2;
00234   EXPECT_TRUE(kin.calcFwdKin(joints, result));
00235   expected = Eigen::Translation3d(-0.4318, 0.12446, 1.08548);
00236   expected.rotate(Eigen::AngleAxis<double> (-M_PI_2, Eigen::Vector3d(0,1,0)));
00237   EXPECT_TRUE(result.isApprox(expected, 1e-3));
00238 }
00239 
00240 
00241 TEST_F(calcJacobian, inputValidation)
00242 {
00243     Eigen::MatrixXd jacobian;
00244     EXPECT_FALSE(BasicKin().calcJacobian(VectorXd(), jacobian));            // un-init BasicKin & Jnts
00245     EXPECT_FALSE(BasicKin().calcJacobian(VectorXd::Zero(6), jacobian));     // un-init BasicKin
00246     EXPECT_FALSE(kin.calcJacobian(VectorXd(), jacobian));                   // empty joints
00247     EXPECT_FALSE(kin.calcJacobian(VectorXd::Zero(99), jacobian));           // too many joints
00248     EXPECT_FALSE(kin.calcJacobian(VectorXd::Constant(6, 1e10), jacobian));  // joints out-of-range
00249 
00250     EXPECT_TRUE(kin.calcJacobian(VectorXd::Zero(6), jacobian));             // valid input
00251 }
00252 
00253 
00254 TEST_F(calcJacobian, knownPoses)
00255 {
00256     VectorXd joints = VectorXd::Zero(6);
00257     MatrixXd expected, result;
00258 
00259     // all joints 0
00260     EXPECT_TRUE(kin.calcJacobian(joints, result));
00261     expected.resize(6,6);
00262     expected << -0.12446, 0.4318,  0.4318, 0, 0, 0,
00263                  0.41148, 0,       0,      0, 0, 0,
00264                  0,      -0.41148, 0.0203, 0, 0, 0,
00265                  0,       0,       0,      0, 0, 0,
00266                  0,       1,       1,      0, 1, 0,
00267                  1,       0,       0,      1, 0, 1;
00268     EXPECT_TRUE(result.isApprox(expected, 1e-3));
00269 
00270     joints(0) = M_PI_2;
00271     EXPECT_TRUE(kin.calcJacobian(joints, result));
00272     expected << -0.41148, 0,       0,       0,  0, 0,
00273                 -0.12446, 0.4318,  0.4318,  0,  0, 0,
00274                  0,      -0.41148, 0.02032, 0,  0, 0,
00275                  0,      -1,      -1,       0, -1, 0,
00276                  0,       0,       0,       0,  0, 0,
00277                  1,       0,       0,       1,  0, 1;
00278     EXPECT_TRUE(result.isApprox(expected, 1e-3));
00279 
00280     joints(1) = -M_PI_2;
00281     EXPECT_TRUE(kin.calcJacobian(joints, result));
00282     expected <<  0.4318,  0,        0,       0,  0, 0,
00283                 -0.12446, 0.41148, -0.02032, 0,  0, 0,
00284                  0,       0.4318,   0.4318,  0,  0, 0,
00285                  0,      -1,       -1,       0, -1, 0,
00286                  0,       0,        0,      -1,  0, -1,
00287                  1,       0,        0,       0,  0, 0;
00288     EXPECT_TRUE(result.isApprox(expected, 1e-3));
00289 
00290     joints(2) = -M_PI_2;
00291     EXPECT_TRUE(kin.calcJacobian(joints, result));
00292     expected <<  -0.02032, 0,        0,       0,  0,  0,
00293                  -0.12446, 0,       -0.4318,  0,  0,  0,
00294                   0,      -0.02032, -0.02032, 0,  0,  0,
00295                   0,      -1,       -1,       0, -1,  0,
00296                   0,       0,        0,       0,  0,  0,
00297                   1,       0,        0,      -1,  0, -1;
00298     EXPECT_TRUE(result.isApprox(expected, 1e-3));
00299 //        std::cout << joints << std::endl;
00300 //        std::cout << "result: " <<std::endl << result << std::endl;
00301 //        std::cout << "expected: " <<std::endl << expected << std::endl;
00302 
00303     joints(3) = M_PI_2;
00304     EXPECT_TRUE(kin.calcJacobian(joints, result));
00305     expected << -0.02032, 0,        0,       0, 0,  0,
00306                 -0.12446, 0,       -0.4318,  0, 0,  0,
00307                  0,      -0.02032, -0.02032, 0, 0,  0,
00308                  0,      -1,       -1,       0, 0,  0,
00309                  0,       0,        0,       0, 1,  0,
00310                  1,       0,        0,      -1, 0, -1;
00311     EXPECT_TRUE(result.isApprox(expected, 1e-3));
00312 
00313     joints(4) = M_PI_2;
00314     EXPECT_TRUE(kin.calcJacobian(joints, result));
00315     expected << -0.02032, 0,        0,       0, 0,  0,
00316                 -0.12446, 0,       -0.4318,  0, 0,  0,
00317                  0,      -0.02032, -0.02032, 0, 0,  0,
00318                  0,      -1,       -1,       0, 0, -1,
00319                  0,       0,        0,       0, 1,  0,
00320                  1,       0,        0,      -1, 0,  0;
00321     EXPECT_TRUE(result.isApprox(expected, 1e-3));
00322 
00323     joints(5) = M_PI_2;
00324     EXPECT_TRUE(kin.calcJacobian(joints, result));
00325     expected << -0.02032, 0,        0,       0, 0,  0,
00326                 -0.12446, 0,       -0.4318,  0, 0,  0,
00327                  0,      -0.02032, -0.02032, 0, 0,  0,
00328                  0,      -1,       -1,       0, 0, -1,
00329                  0,       0,        0,       0, 1,  0,
00330                  1,       0,        0,      -1, 0,  0;
00331     EXPECT_TRUE(result.isApprox(expected, 1e-3));
00332 }
00333 
00334 
00335 TEST_F(solvePInv, inputValidation)
00336 {
00337   VectorXd vResult;
00338 
00339   EXPECT_FALSE(kin.solvePInv(MatrixXd(), VectorXd(), vResult));
00340   EXPECT_FALSE(kin.solvePInv(MatrixXd(6,3), VectorXd(1), vResult));
00341   EXPECT_TRUE(kin.solvePInv(MatrixXd::Zero(6,3), VectorXd::Zero(6), vResult));
00342   EXPECT_TRUE(kin.solvePInv(MatrixXd::Zero(3,6), VectorXd::Zero(3), vResult));
00343   EXPECT_TRUE(kin.solvePInv(MatrixXd::Zero(6,6), VectorXd::Zero(6), vResult));
00344 }
00345 
00346 
00347 TEST_F(solvePInv, randomInputs)
00348 {
00349   VectorXd vResult;
00350 
00351   // Test square matrices
00352   for (int i=0; i<100; ++i)
00353     ASSERT_TRUE(test_random(10, 10));
00354 
00355   // Test over-constrained matrices
00356   for (int i=0; i<100; ++i)
00357     ASSERT_TRUE(test_random(10, 5));
00358 }
00359 
00360 
00361 int main(int argc, char **argv)
00362 {
00363   testing::InitGoogleTest(&argc, argv);
00364   return RUN_ALL_TESTS();
00365 }
00366 


constrained_ik
Author(s): Chris Lewis , Jeremy Zoss , Dan Solomon
autogenerated on Mon Oct 6 2014 00:52:26