3 #include <gtest/gtest.h>
12 TEST(TesseractKinematicsUnit, UtilsHarmonizeTowardZeroUnit)
15 q[0] = (4 * M_PI) + M_PI_4;
16 q[1] = -(4 * M_PI) - M_PI_4;
18 tesseract_kinematics::harmonizeTowardZero<double>(q, { 0, 1 });
19 EXPECT_NEAR(q[0], M_PI_4, 1e-6);
20 EXPECT_NEAR(q[1], -M_PI_4, 1e-6);
25 tesseract_kinematics::harmonizeTowardZero<double>(q, { 0, 1 });
26 EXPECT_NEAR(q[0], M_PI_4, 1e-6);
27 EXPECT_NEAR(q[1], -M_PI_4, 1e-6);
32 tesseract_kinematics::harmonizeTowardZero<double>(q, { 0, 1 });
33 EXPECT_NEAR(q[0], -3 * M_PI_4, 1e-6);
34 EXPECT_NEAR(q[1], 3 * M_PI_4, 1e-6);
37 TEST(TesseractKinematicsUnit, UtilsHarmonizeTowardMedianUnit)
39 Eigen::MatrixX2d c(2, 2);
45 m[0] = (c(0, 0) + c(0, 1)) / 2.0;
46 m[1] = (c(1, 0) + c(1, 1)) / 2.0;
49 q[0] = (4 * M_PI) + M_PI_4;
50 q[1] = -(4 * M_PI) - M_PI_4;
52 tesseract_kinematics::harmonizeTowardMedian<double>(q, { 0, 1 }, c);
53 EXPECT_NEAR(q[0], M_PI_4, 1e-6);
54 EXPECT_NEAR(q[1], -M_PI_4, 1e-6);
55 EXPECT_TRUE(std::abs(q[0] - m[0]) < (M_PI + 1e-6));
56 EXPECT_TRUE(std::abs(q[1] - m[1]) < (M_PI + 1e-6));
61 tesseract_kinematics::harmonizeTowardMedian<double>(q, { 0, 1 }, c);
62 EXPECT_NEAR(q[0], M_PI_4, 1e-6);
63 EXPECT_NEAR(q[1], -M_PI_4, 1e-6);
64 EXPECT_TRUE(std::abs(q[0] - m[0]) < (M_PI + 1e-6));
65 EXPECT_TRUE(std::abs(q[1] - m[1]) < (M_PI + 1e-6));
70 tesseract_kinematics::harmonizeTowardMedian<double>(q, { 0, 1 }, c);
71 EXPECT_NEAR(q[0], -3 * M_PI_4, 1e-6);
72 EXPECT_NEAR(q[1], 3 * M_PI_4, 1e-6);
73 EXPECT_TRUE(std::abs(q[0] - m[0]) < (M_PI + 1e-6));
74 EXPECT_TRUE(std::abs(q[1] - m[1]) < (M_PI + 1e-6));
77 c(0, 0) = (10 * M_PI) + M_PI_4 - M_PI;
78 c(0, 1) = (10 * M_PI) + M_PI_4 + M_PI;
79 c(1, 0) = (10 * M_PI) + M_PI_4 - M_PI;
80 c(1, 1) = (10 * M_PI) + M_PI_4 + M_PI;
81 m[0] = (c(0, 0) + c(0, 1)) / 2.0;
82 m[1] = (c(1, 0) + c(1, 1)) / 2.0;
84 q[0] = (4 * M_PI) + M_PI_4;
85 q[1] = -(4 * M_PI) - M_PI_4;
87 tesseract_kinematics::harmonizeTowardMedian<double>(q, { 0, 1 }, c);
88 EXPECT_NEAR(q[0], m[0], 1e-6);
89 EXPECT_NEAR(q[1], m[1] - M_PI_2, 1e-6);
90 EXPECT_TRUE(std::abs(q[0] - m[0]) < (M_PI + 1e-6));
91 EXPECT_TRUE(std::abs(q[1] - m[1]) < (M_PI + 1e-6));
96 tesseract_kinematics::harmonizeTowardMedian<double>(q, { 0, 1 }, c);
97 EXPECT_NEAR(q[0], m[0], 1e-6);
98 EXPECT_NEAR(q[1], m[1] - M_PI_2, 1e-6);
99 EXPECT_TRUE(std::abs(q[0] - m[0]) < (M_PI + 1e-6));
100 EXPECT_TRUE(std::abs(q[1] - m[1]) < (M_PI + 1e-6));
105 tesseract_kinematics::harmonizeTowardMedian<double>(q, { 0, 1 }, c);
106 EXPECT_NEAR(q[0], m[0] - M_PI, 1e-6);
107 EXPECT_NEAR(q[1], m[1] + M_PI_2, 1e-6);
108 EXPECT_TRUE(std::abs(q[0] - m[0]) < (M_PI + 1e-6));
109 EXPECT_TRUE(std::abs(q[1] - m[1]) < (M_PI + 1e-6));
112 c(0, 0) = (-1 * ((10 * M_PI) + M_PI_4)) - M_PI;
113 c(0, 1) = (-1 * ((10 * M_PI) + M_PI_4)) + M_PI;
114 c(1, 0) = (-1 * ((10 * M_PI) + M_PI_4)) - M_PI;
115 c(1, 1) = (-1 * ((10 * M_PI) + M_PI_4)) + M_PI;
116 m[0] = (c(0, 0) + c(0, 1)) / 2.0;
117 m[1] = (c(1, 0) + c(1, 1)) / 2.0;
119 q[0] = (4 * M_PI) + M_PI_4;
120 q[1] = -(4 * M_PI) - M_PI_4;
122 tesseract_kinematics::harmonizeTowardMedian<double>(q, { 0, 1 }, c);
123 EXPECT_NEAR(q[0], m[0] + M_PI_2, 1e-6);
124 EXPECT_NEAR(q[1], m[1], 1e-6);
125 EXPECT_TRUE(std::abs(q[0] - m[0]) < (M_PI + 1e-6));
126 EXPECT_TRUE(std::abs(q[1] - m[1]) < (M_PI + 1e-6));
131 tesseract_kinematics::harmonizeTowardMedian<double>(q, { 0, 1 }, c);
132 EXPECT_NEAR(q[0], m[0] + M_PI_2, 1e-6);
133 EXPECT_NEAR(q[1], m[1], 1e-6);
134 EXPECT_TRUE(std::abs(q[0] - m[0]) < (M_PI + 1e-6));
135 EXPECT_TRUE(std::abs(q[1] - m[1]) < (M_PI + 1e-6));
140 tesseract_kinematics::harmonizeTowardMedian<double>(q, { 0, 1 }, c);
141 EXPECT_NEAR(q[0], m[0] - M_PI_2, 1e-6);
142 EXPECT_NEAR(q[1], m[1] + M_PI, 1e-6);
143 EXPECT_TRUE(std::abs(q[0] - m[0]) < (M_PI + 1e-6));
144 EXPECT_TRUE(std::abs(q[1] - m[1]) < (M_PI + 1e-6));
147 template <
typename FloatType>
151 auto expect_unique_solutions = [](
const std::vector<tesseract_kinematics::VectorX<FloatType>>& solutions) {
152 for (
auto sol_1 = solutions.begin(); sol_1 != solutions.end() - 1; ++sol_1)
154 for (
auto sol_2 = sol_1 + 1; sol_2 != solutions.end(); ++sol_2)
157 sol_1->template cast<double>(), sol_2->template cast<double>(), 1e-6));
163 double max_diff = 1e-6;
164 Eigen::MatrixX2d limits(3, 2);
165 limits << 0, 2.0 * M_PI, 0, 2.0 * M_PI, 0, 2.0 * M_PI;
166 std::vector<Eigen::Index> redundancy_capable_joints = { 0, 1, 2 };
172 std::vector<tesseract_kinematics::VectorX<FloatType>> solutions =
173 tesseract_kinematics::getRedundantSolutions<FloatType>(q, limits, redundancy_capable_joints);
175 solutions.push_back(q);
177 EXPECT_EQ(solutions.size(), 8);
178 expect_unique_solutions(solutions);
182 limits << -2.0 * M_PI, 2.0 * M_PI, -2.0 * M_PI, 2.0 * M_PI, -2.0 * M_PI, 2.0 * M_PI;
183 std::vector<tesseract_kinematics::VectorX<FloatType>> solutions =
184 tesseract_kinematics::getRedundantSolutions<FloatType>(q, limits, redundancy_capable_joints);
186 solutions.push_back(q);
188 EXPECT_EQ(solutions.size(), 27);
189 expect_unique_solutions(solutions);
193 limits << -2.0 * M_PI, 2.0 * M_PI, -2.0 * M_PI, 2.0 * M_PI, -2.0 * M_PI, 2.0 * M_PI;
194 q << static_cast<FloatType>(-4.0 * M_PI),
static_cast<FloatType
>(-4.0 * M_PI),
static_cast<FloatType
>(4.0 * M_PI);
196 std::vector<tesseract_kinematics::VectorX<FloatType>> solutions =
197 tesseract_kinematics::getRedundantSolutions<FloatType>(q, limits, redundancy_capable_joints);
199 solutions.push_back(q);
201 EXPECT_EQ(solutions.size(), 27);
202 expect_unique_solutions(solutions);
207 double max_diff = 1.0e-6;
208 Eigen::MatrixX2d limits(4, 2);
209 limits << -2.0 * M_PI, 2.0 * M_PI, -2.0 * M_PI, 2.0 * M_PI, -2.0 * M_PI, 2.0 * M_PI, -2.0 * M_PI, 2.0 * M_PI;
212 q << static_cast<FloatType>(-4.0 * M_PI),
static_cast<FloatType
>(-4.0 * M_PI),
static_cast<FloatType
>(0.0),
213 static_cast<FloatType
>(4.0 * M_PI);
216 std::vector<Eigen::Index> redundancy_capable_joints = { 0, 1, 3 };
218 std::vector<tesseract_kinematics::VectorX<FloatType>> solutions =
219 tesseract_kinematics::getRedundantSolutions<FloatType>(q, limits, redundancy_capable_joints);
221 solutions.push_back(q);
223 EXPECT_EQ(solutions.size(), 27);
224 expect_unique_solutions(solutions);
228 Eigen::MatrixX2d limits(4, 2);
229 limits << -2.0 * M_PI, 2.0 * M_PI, -2.0 * M_PI, 2.0 * M_PI, -2.0 * M_PI, 2.0 * M_PI, -2.0 * M_PI, 2.0 * M_PI;
232 q << static_cast<FloatType>(-4.0 * M_PI),
static_cast<FloatType
>(-4.0 * M_PI),
static_cast<FloatType
>(0.0),
233 static_cast<FloatType
>(4.0 * M_PI);
235 std::vector<Eigen::Index> redundancy_capable_joints = {};
236 std::vector<tesseract_kinematics::VectorX<FloatType>> solutions =
237 tesseract_kinematics::getRedundantSolutions<FloatType>(q, limits, redundancy_capable_joints);
239 EXPECT_EQ(solutions.size(), 0);
241 redundancy_capable_joints = { 10 };
244 EXPECT_THROW(tesseract_kinematics::getRedundantSolutions<FloatType>(q, limits, redundancy_capable_joints),
249 Eigen::MatrixX2d limits(4, 2);
250 limits << -std::numeric_limits<double>::infinity(), 2.0 * M_PI, -2.0 * M_PI, 2.0 * M_PI, -2.0 * M_PI, 2.0 * M_PI,
251 -2.0 * M_PI, 2.0 * M_PI;
254 q << static_cast<FloatType>(-4.0 * M_PI),
static_cast<FloatType
>(-4.0 * M_PI),
static_cast<FloatType
>(0.0),
255 static_cast<FloatType
>(4.0 * M_PI);
257 std::vector<Eigen::Index> redundancy_capable_joints = { 0 };
258 std::vector<tesseract_kinematics::VectorX<FloatType>> solutions =
259 tesseract_kinematics::getRedundantSolutions<FloatType>(q, limits, redundancy_capable_joints);
261 EXPECT_EQ(solutions.size(), 0);
265 Eigen::MatrixX2d limits(4, 2);
266 limits << -2.0 * M_PI, std::numeric_limits<double>::infinity(), -2.0 * M_PI, 2.0 * M_PI, -2.0 * M_PI, 2.0 * M_PI,
267 -2.0 * M_PI, 2.0 * M_PI;
270 q << static_cast<FloatType>(-4.0 * M_PI),
static_cast<FloatType
>(-4.0 * M_PI),
static_cast<FloatType
>(0.0),
271 static_cast<FloatType
>(4.0 * M_PI);
273 std::vector<Eigen::Index> redundancy_capable_joints = { 0, 1, 3 };
274 std::vector<tesseract_kinematics::VectorX<FloatType>> solutions =
275 tesseract_kinematics::getRedundantSolutions<FloatType>(q, limits, redundancy_capable_joints);
277 EXPECT_EQ(solutions.size(), 0);
281 TEST(TesseractKinematicsUnit, RedundantSolutionsUnit)
283 runRedundantSolutionsTest<float>();
284 runRedundantSolutionsTest<double>();
287 TEST(TesseractKinematicsUnit, UtilsNearSingularityUnit)
295 Eigen::VectorXd jv = Eigen::VectorXd::Zero(6);
296 Eigen::MatrixXd jacobian = fwd_kin.
calcJacobian(jv,
"tool0");
300 jv[4] = 1 * M_PI / 180.0;
305 jv[4] = 2 * M_PI / 180.0;
313 TEST(TesseractKinematicsUnit, UtilscalcManipulabilityUnit)
321 Eigen::VectorXd jv = Eigen::VectorXd::Zero(6);
322 Eigen::MatrixXd jacobian = fwd_kin.
calcJacobian(jv,
"tool0");
325 EXPECT_NEAR(m.
m.
volume, 0, 1e-6);
345 EXPECT_NEAR(m.
m.
volume, 0, 1e-6);
365 TEST(TesseractKinematicsUnit, solvePInv_OverdeterminedSystem)
367 Eigen::MatrixXd A(4, 2);
368 A << 1, 2, 3, 4, 5, 6, 7, 8;
370 Eigen::VectorXd b(4);
373 Eigen::VectorXd x(A.cols());
376 EXPECT_TRUE(success);
377 EXPECT_EQ(x.size(), 2);
380 Eigen::VectorXd b_approx = A * x;
381 EXPECT_TRUE((b - b_approx).norm() < 1e-4);
384 TEST(TesseractKinematicsUnit, solvePInv_UnderdeterminedSystem)
386 Eigen::MatrixXd A(2, 4);
387 A << 1, 2, 3, 4, 5, 6, 7, 8;
389 Eigen::VectorXd b(2);
392 Eigen::VectorXd x(A.cols());
395 EXPECT_TRUE(success);
396 EXPECT_EQ(x.size(), 4);
399 Eigen::VectorXd b_approx = A * x;
400 EXPECT_TRUE((b - b_approx).norm() < 1e-4);
403 TEST(TesseractKinematicsUnit, solvePInv_SizeMismatch)
405 Eigen::MatrixXd A(3, 3);
406 A << 1, 2, 3, 4, 5, 6, 7, 8, 9;
408 Eigen::VectorXd b(2);
410 Eigen::VectorXd x(3);
412 EXPECT_FALSE(success);
415 TEST(TesseractKinematicsUnit, solvePInv_EmptyMatrix)
417 Eigen::MatrixXd A(0, 0);
418 Eigen::VectorXd b(0);
422 EXPECT_FALSE(success);
428 Eigen::MatrixXd approx = A * P * A;
429 return (A - approx).norm() < tolerance;
432 TEST(TesseractKinematicsUnit, dampedPInv_FullRankSquareMatrix)
434 Eigen::MatrixXd A(3, 3);
435 A << 1, 2, 3, 4, 5, 6, 7, 8, 10;
437 Eigen::MatrixXd P(3, 3);
439 EXPECT_TRUE(success);
440 EXPECT_EQ(P.rows(), 3);
441 EXPECT_EQ(P.cols(), 3);
445 TEST(TesseractKinematicsUnit, dampedPInv_RankDeficientMatrix)
447 Eigen::MatrixXd A(3, 3);
448 A << 1, 2, 3, 2, 4, 6, 3, 6, 9;
450 Eigen::MatrixXd P(3, 3);
452 EXPECT_TRUE(success);
453 EXPECT_EQ(P.rows(), 3);
454 EXPECT_EQ(P.cols(), 3);
458 TEST(TesseractKinematicsUnit, dampedPInv_OverdeterminedMatrix)
460 Eigen::MatrixXd A(4, 2);
461 A << 1, 2, 3, 4, 5, 6, 7, 8;
463 Eigen::MatrixXd P(2, 4);
465 EXPECT_TRUE(success);
466 EXPECT_EQ(P.rows(), 2);
467 EXPECT_EQ(P.cols(), 4);
471 TEST(TesseractKinematicsUnit, dampedPInv_UnderdeterminedMatrix)
473 Eigen::MatrixXd A(2, 4);
474 A << 1, 2, 3, 4, 5, 6, 7, 8;
476 Eigen::MatrixXd P(4, 2);
478 EXPECT_TRUE(success);
479 EXPECT_EQ(P.rows(), 4);
480 EXPECT_EQ(P.cols(), 2);
484 TEST(TesseractKinematicsUnit, dampedPInv_EmptyMatrix)
489 EXPECT_FALSE(success);
492 int main(
int argc,
char** argv)
494 testing::InitGoogleTest(&argc, argv);
496 return RUN_ALL_TESTS();