00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
00030
00031
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
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));
00110 EXPECT_FALSE(BasicKin().linkTransforms(VectorXd(), poses, std::vector<std::string>()));
00111 EXPECT_FALSE(BasicKin().linkTransforms(VectorXd(), poses, link_names));
00112 EXPECT_FALSE(BasicKin().linkTransforms(VectorXd::Zero(6), poses, std::vector<std::string>()));
00113 EXPECT_FALSE(BasicKin().linkTransforms(VectorXd::Zero(6), poses, link_names));
00114
00115 EXPECT_FALSE(kin.linkTransforms(VectorXd(), poses, std::vector<std::string>()));
00116 EXPECT_FALSE(kin.linkTransforms(VectorXd::Zero(99), poses, link_names));
00117 EXPECT_FALSE(kin.linkTransforms(VectorXd::Constant(6, 1e10), poses, link_names));
00118
00119 EXPECT_TRUE(kin.linkTransforms(VectorXd::Zero(6), poses, link_names));
00120 EXPECT_TRUE(kin.linkTransforms(VectorXd::Zero(6), poses));
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));
00124
00125 link_names[5] = "fail_on_this";
00126 EXPECT_FALSE(kin.linkTransforms(VectorXd::Zero(6), poses, link_names));
00127 link_names_short[0] = link_names[5];
00128 EXPECT_FALSE(kin.linkTransforms(VectorXd::Zero(6), poses, link_names_short));
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
00143 joint_angles = VectorXd::Zero(6);
00144 expected[0] = Frame(Vector(0,0,.674));
00145 expected[1] = Frame(Vector(0,0,.674));
00146 expected[2] = Frame(Vector(.4318,.12446,.674));
00147 expected[3] = Frame(Vector(.41148,.12446,1.1058));
00148 expected[4] = Frame(Vector(.41148,.12446,1.1058));
00149 expected[5] = Frame(Vector(.41148,.12446,1.1058));
00150 EXPECT_TRUE(kin.linkTransforms(joint_angles, actual, link_names));
00151 EXPECT_TRUE(comparePoses(actual, expected, 1e-4));
00152 EXPECT_TRUE(kin.linkTransforms(joint_angles, actual));
00153 EXPECT_TRUE(comparePoses(actual, expected, 1e-4));
00154
00155
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));
00164 EXPECT_TRUE(comparePoses(actual, expected, 1e-4));
00165 EXPECT_TRUE(kin.linkTransforms(joint_angles, actual));
00166 EXPECT_TRUE(comparePoses(actual, expected, 1e-4));
00167
00168
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));
00178 EXPECT_TRUE(comparePoses(actual, expected, 1e-4));
00179 EXPECT_TRUE(kin.linkTransforms(joint_angles, actual));
00180 EXPECT_TRUE(comparePoses(actual, expected, 1e-4));
00181
00182
00183 joint_angles = VectorXd::Zero(6);
00184 std::vector<std::string> link_names_short(link_names.begin()+1, link_names.end()-1);
00185
00186 expected[1] = Frame(Vector(0,0,.674));
00187 expected[2] = Frame(Vector(.4318,.12446,.674));
00188 expected[3] = Frame(Vector(.41148,.12446,1.1058));
00189 expected[4] = Frame(Vector(.41148,.12446,1.1058));
00190
00191 std::vector<Frame> expected_short(expected.begin()+1, expected.end()-1);
00192 EXPECT_TRUE(kin.linkTransforms(joint_angles, actual, link_names_short));
00193 EXPECT_TRUE(comparePoses(actual, expected_short, 1e-4));
00194 EXPECT_TRUE(kin.linkTransforms(joint_angles, actual));
00195 EXPECT_FALSE(comparePoses(actual, expected, 1e-4));
00196 }
00197
00198
00199 TEST_F(calcFwdKin, inputValidation)
00200 {
00201
00202 Eigen::Affine3d pose;
00203
00204 EXPECT_FALSE(BasicKin().calcFwdKin(VectorXd(), pose));
00205 EXPECT_FALSE(BasicKin().calcFwdKin(VectorXd::Zero(6), pose));
00206 EXPECT_FALSE(kin.calcFwdKin(VectorXd(), pose));
00207 EXPECT_FALSE(kin.calcFwdKin(VectorXd::Zero(99), pose));
00208 EXPECT_FALSE(kin.calcFwdKin(VectorXd::Constant(6, 1e10), pose));
00209
00210 EXPECT_TRUE(kin.calcFwdKin(VectorXd::Zero(6), pose));
00211 }
00212
00213
00214 TEST_F(calcFwdKin, knownPoses)
00215 {
00216 VectorXd joints = VectorXd::Zero(6);
00217 Eigen::Affine3d expected, result;
00218
00219
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
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
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));
00245 EXPECT_FALSE(BasicKin().calcJacobian(VectorXd::Zero(6), jacobian));
00246 EXPECT_FALSE(kin.calcJacobian(VectorXd(), jacobian));
00247 EXPECT_FALSE(kin.calcJacobian(VectorXd::Zero(99), jacobian));
00248 EXPECT_FALSE(kin.calcJacobian(VectorXd::Constant(6, 1e10), jacobian));
00249
00250 EXPECT_TRUE(kin.calcJacobian(VectorXd::Zero(6), jacobian));
00251 }
00252
00253
00254 TEST_F(calcJacobian, knownPoses)
00255 {
00256 VectorXd joints = VectorXd::Zero(6);
00257 MatrixXd expected, result;
00258
00259
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
00300
00301
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
00352 for (int i=0; i<100; ++i)
00353 ASSERT_TRUE(test_random(10, 10));
00354
00355
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